diff --git a/content/blog/ggplot2-styling/d3-bundle-5.16.0/d3-bundle.min.js b/content/blog/ggplot2-styling/d3-bundle-5.16.0/d3-bundle.min.js new file mode 100644 index 000000000..4ebf9dfea --- /dev/null +++ b/content/blog/ggplot2-styling/d3-bundle-5.16.0/d3-bundle.min.js @@ -0,0 +1,26 @@ +// https://d3js.org/d3-selection/ v1.4.2 Copyright 2020 Mike Bostock +!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t=t||self).d3=t.d3||{})}(this,function(t){"use strict";var n="http://www.w3.org/1999/xhtml",e={svg:"http://www.w3.org/2000/svg",xhtml:n,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function r(t){var n=t+="",r=n.indexOf(":");return r>=0&&"xmlns"!==(n=t.slice(0,r))&&(t=t.slice(r+1)),e.hasOwnProperty(n)?{space:e[n],local:t}:t}function i(t){var e=r(t);return(e.local?function(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}:function(t){return function(){var e=this.ownerDocument,r=this.namespaceURI;return r===n&&e.documentElement.namespaceURI===n?e.createElement(t):e.createElementNS(r,t)}})(e)}function o(){}function u(t){return null==t?o:function(){return this.querySelector(t)}}function c(){return[]}function s(t){return null==t?c:function(){return this.querySelectorAll(t)}}function a(t){return function(){return this.matches(t)}}function l(t){return new Array(t.length)}function f(t,n){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=n}f.prototype={constructor:f,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,n){return this._parent.insertBefore(t,n)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var h="$";function p(t,n,e,r,i,o){for(var u,c=0,s=n.length,a=o.length;cn?1:t>=n?0:NaN}function d(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function y(t,n){return t.style.getPropertyValue(n)||d(t).getComputedStyle(t,null).getPropertyValue(n)}function m(t){return t.trim().split(/^|\s+/)}function g(t){return t.classList||new w(t)}function w(t){this._node=t,this._names=m(t.getAttribute("class")||"")}function A(t,n){for(var e=g(t),r=-1,i=n.length;++r=0&&(this._names.splice(n,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var B={};(t.event=null,"undefined"!=typeof document)&&("onmouseenter"in document.documentElement||(B={mouseenter:"mouseover",mouseleave:"mouseout"}));function q(t,n,e){return t=D(t,n,e),function(n){var e=n.relatedTarget;e&&(e===this||8&e.compareDocumentPosition(this))||t.call(this,n)}}function D(n,e,r){return function(i){var o=t.event;t.event=i;try{n.call(this,this.__data__,e,r)}finally{t.event=o}}}function M(t){return function(){var n=this.__on;if(n){for(var e,r=0,i=-1,o=n.length;r=S&&(S=x+1);!(A=g[S])&&++S=0;)(r=i[o])&&(u&&4^r.compareDocumentPosition(u)&&u.parentNode.insertBefore(r,u),u=r);return this},sort:function(t){function n(n,e){return n&&e?t(n.__data__,e.__data__):!n-!e}t||(t=v);for(var e=this._groups,r=e.length,i=new Array(r),o=0;o1?this.each((null==n?function(t){return function(){this.style.removeProperty(t)}}:"function"==typeof n?function(t,n,e){return function(){var r=n.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,e)}}:function(t,n,e){return function(){this.style.setProperty(t,n,e)}})(t,n,null==e?"":e)):y(this.node(),t)},property:function(t,n){return arguments.length>1?this.each((null==n?function(t){return function(){delete this[t]}}:"function"==typeof n?function(t,n){return function(){var e=n.apply(this,arguments);null==e?delete this[t]:this[t]=e}}:function(t,n){return function(){this[t]=n}})(t,n)):this.node()[t]},classed:function(t,n){var e=m(t+"");if(arguments.length<2){for(var r=g(this.node()),i=-1,o=e.length;++i=0&&(n=t.slice(e+1),t=t.slice(0,e)),{type:t,name:n}})}(t+""),u=o.length;if(!(arguments.length<2)){for(c=n?O:M,null==e&&(e=!1),r=0;r>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===n?m(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===n?m(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=h.exec(t))?new M(e[1],e[2],e[3],1):(e=l.exec(t))?new M(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=u.exec(t))?m(e[1],e[2],e[3],e[4]):(e=c.exec(t))?m(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=g.exec(t))?R(e[1],e[2]/100,e[3]/100,1):(e=f.exec(t))?R(e[1],e[2]/100,e[3]/100,e[4]):d.hasOwnProperty(t)?w(d[t]):"transparent"===t?new M(NaN,NaN,NaN,0):null}function w(t){return new M(t>>16&255,t>>8&255,255&t,1)}function m(t,e,n,i){return i<=0&&(t=e=n=NaN),new M(t,e,n,i)}function N(t){return t instanceof i||(t=y(t)),t?new M((t=t.rgb()).r,t.g,t.b,t.opacity):new M}function k(t,e,n,i){return 1===arguments.length?N(t):new M(t,e,n,null==i?1:i)}function M(t,e,n,i){this.r=+t,this.g=+e,this.b=+n,this.opacity=+i}function v(){return"#"+q(this.r)+q(this.g)+q(this.b)}function x(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"rgb(":"rgba(")+Math.max(0,Math.min(255,Math.round(this.r)||0))+", "+Math.max(0,Math.min(255,Math.round(this.g)||0))+", "+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===t?")":", "+t+")")}function q(t){return((t=Math.max(0,Math.min(255,Math.round(t)||0)))<16?"0":"")+t.toString(16)}function R(t,e,n,i){return i<=0?t=e=n=NaN:n<=0||n>=1?t=e=NaN:e<=0&&(t=NaN),new H(t,e,n,i)}function E(t){if(t instanceof H)return new H(t.h,t.s,t.l,t.opacity);if(t instanceof i||(t=y(t)),!t)return new H;if(t instanceof H)return t;var e=(t=t.rgb()).r/255,n=t.g/255,r=t.b/255,a=Math.min(e,n,r),s=Math.max(e,n,r),o=NaN,h=s-a,l=(s+a)/2;return h?(o=e===s?(n-r)/h+6*(n0&&l<1?0:o,new H(o,h,l,t.opacity)}function $(t,e,n,i){return 1===arguments.length?E(t):new H(t,e,n,null==i?1:i)}function H(t,e,n,i){this.h=+t,this.s=+e,this.l=+n,this.opacity=+i}function j(t,e,n){return 255*(t<60?e+(n-e)*t/60:t<180?n:t<240?e+(n-e)*(240-t)/60:e)}e(i,y,{copy:function(t){return Object.assign(new this.constructor,this,t)},displayable:function(){return this.rgb().displayable()},hex:p,formatHex:p,formatHsl:function(){return E(this).formatHsl()},formatRgb:b,toString:b}),e(M,k,n(i,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new M(this.r*t,this.g*t,this.b*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new M(this.r*t,this.g*t,this.b*t,this.opacity)},rgb:function(){return this},displayable:function(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:v,formatHex:v,formatRgb:x,toString:x})),e(H,$,n(i,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new H(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new H(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=this.h%360+360*(this.h<0),e=isNaN(t)||isNaN(this.s)?0:this.s,n=this.l,i=n+(n<.5?n:1-n)*e,r=2*n-i;return new M(j(t>=240?t-240:t+120,r,i),j(t,r,i),j(t<120?t+240:t-120,r,i),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl:function(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"hsl(":"hsla(")+(this.h||0)+", "+100*(this.s||0)+"%, "+100*(this.l||0)+"%"+(1===t?")":", "+t+")")}}));var O=Math.PI/180,P=180/Math.PI,I=.96422,S=1,_=.82521,z=4/29,C=6/29,L=3*C*C,A=C*C*C;function B(t){if(t instanceof F)return new F(t.l,t.a,t.b,t.opacity);if(t instanceof V)return W(t);t instanceof M||(t=N(t));var e,n,i=Q(t.r),r=Q(t.g),a=Q(t.b),s=G((.2225045*i+.7168786*r+.0606169*a)/S);return i===r&&r===a?e=n=s:(e=G((.4360747*i+.3850649*r+.1430804*a)/I),n=G((.0139322*i+.0971045*r+.7141733*a)/_)),new F(116*s-16,500*(e-s),200*(s-n),t.opacity)}function D(t,e,n,i){return 1===arguments.length?B(t):new F(t,e,n,null==i?1:i)}function F(t,e,n,i){this.l=+t,this.a=+e,this.b=+n,this.opacity=+i}function G(t){return t>A?Math.pow(t,1/3):t/L+z}function J(t){return t>C?t*t*t:L*(t-z)}function K(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function Q(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function T(t){if(t instanceof V)return new V(t.h,t.c,t.l,t.opacity);if(t instanceof F||(t=B(t)),0===t.a&&0===t.b)return new V(NaN,0=0&&(t=n.slice(r+1),n=n.slice(0,r)),n&&!e.hasOwnProperty(n))throw new Error("unknown type: "+n);return{type:n,name:t}})}function i(n,e){for(var t,r=0,o=n.length;r0)for(var t,r,o=new Array(t),i=0;i=1?(e=1,n-1):Math.floor(e*n),o=t[a],u=t[a+1],i=a>0?t[a-1]:2*o-u,l=a180||r<-180?r-360*Math.round(r/360):r):o(isNaN(t)?n:t)}function l(t){return 1==(t=+t)?c:function(n,r){return r-n?function(t,n,r){return t=Math.pow(t,r),n=Math.pow(n,r)-t,r=1/r,function(e){return Math.pow(t+e*n,r)}}(n,r,t):o(isNaN(n)?r:n)}}function c(t,n){var r=n-t;return r?u(t,r):o(isNaN(t)?n:t)}var f=function t(r){var e=l(r);function a(t,r){var a=e((t=n.rgb(t)).r,(r=n.rgb(r)).r),o=e(t.g,r.g),u=e(t.b,r.b),i=c(t.opacity,r.opacity);return function(n){return t.r=a(n),t.g=o(n),t.b=u(n),t.opacity=i(n),t+""}}return a.gamma=t,a}(1);function s(t){return function(r){var e,a,o=r.length,u=new Array(o),i=new Array(o),l=new Array(o);for(e=0;eo&&(a=n.slice(o,a),i[u]?i[u]+=a:i[++u]=a),(r=r[0])===(e=e[0])?i[u]?i[u]+=e:i[++u]=e:(i[++u]=null,l.push({i:u,x:m(r,e)})),o=x.lastIndex;return o180?n+=360:n-t>180&&(t+=360),o.push({i:r.push(a(r)+"rotate(",null,e)-2,x:m(t,n)})):n&&r.push(a(r)+"rotate("+n+e)}(o.rotate,u.rotate,i,l),function(t,n,r,o){t!==n?o.push({i:r.push(a(r)+"skewX(",null,e)-2,x:m(t,n)}):n&&r.push(a(r)+"skewX("+n+e)}(o.skewX,u.skewX,i,l),function(t,n,r,e,o,u){if(t!==r||n!==e){var i=o.push(a(o)+"scale(",null,",",null,")");u.push({i:i-4,x:m(t,r)},{i:i-2,x:m(n,e)})}else 1===r&&1===e||o.push(a(o)+"scale("+r+","+e+")")}(o.scaleX,o.scaleY,u.scaleX,u.scaleY,i,l),o=u=null,function(t){for(var n,r=-1,e=l.length;++r=0&&e._call.call(null,t),e=e._next;--o}function h(){c=(l=a.now())+f,o=i=0;try{d()}finally{o=0,function(){var t,o,i=n,r=1/0;for(;i;)i._call?(r>i._time&&(r=i._time),t=i,i=i._next):(o=i._next,i._next=null,i=t?t._next=o:n=o);e=t,v(r)}(),c=0}}function y(){var t=a.now(),n=t-l;n>u&&(f-=n,l=t)}function v(t){o||(i&&(i=clearTimeout(i)),t-c>24?(t<1/0&&(i=setTimeout(h,t-a.now()-f)),r&&(r=clearInterval(r))):(r||(l=a.now(),r=setInterval(y,u)),o=1,s(h)))}p.prototype=w.prototype={constructor:p,restart:function(t,o,i){if("function"!=typeof t)throw new TypeError("callback is not a function");i=(null==i?_():+i)+(null==o?0:+o),this._next||e===this||(e?e._next=this:n=this,e=this),this._call=t,this._time=i,v()},stop:function(){this._call&&(this._call=null,this._time=1/0,v())}},t.interval=function(t,n,e){var o=new p,i=n;return null==n?(o.restart(t,n,e),o):(n=+n,e=null==e?_():+e,o.restart(function r(u){u+=i,o.restart(r,i+=n,e),t(u)},n,e),o)},t.now=_,t.timeout=function(t,n,e){var o=new p;return n=null==n?0:+n,o.restart(function(e){o.stop(),t(e+n)},n,e),o},t.timer=w,t.timerFlush=d,Object.defineProperty(t,"__esModule",{value:!0})}); + +// https://d3js.org/d3-transition/ v1.3.2 Copyright 2019 Mike Bostock +!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("d3-selection"),require("d3-dispatch"),require("d3-timer"),require("d3-interpolate"),require("d3-color"),require("d3-ease")):"function"==typeof define&&define.amd?define(["exports","d3-selection","d3-dispatch","d3-timer","d3-interpolate","d3-color","d3-ease"],n):n((t=t||self).d3=t.d3||{},t.d3,t.d3,t.d3,t.d3,t.d3,t.d3)}(this,function(t,n,e,r,i,o,u){"use strict";var a=e.dispatch("start","end","cancel","interrupt"),s=[],l=0,f=1,c=2,h=3,d=4,_=5,v=6;function p(t,n,e,i,o,u){var p=t.__transition;if(p){if(e in p)return}else t.__transition={};!function(t,n,e){var i,o=t.__transition;function u(l){var _,p,y,m;if(e.state!==f)return s();for(_ in o)if((m=o[_]).name===e.name){if(m.state===h)return r.timeout(u);m.state===d?(m.state=v,m.timer.stop(),m.on.call("interrupt",t,t.__data__,m.index,m.group),delete o[_]):+_l)throw new Error("too late; already scheduled");return e}function m(t,n){var e=w(t,n);if(e.state>h)throw new Error("too late; already running");return e}function w(t,n){var e=t.__transition;if(!e||!(e=e[n]))throw new Error("transition not found");return e}function g(t,n){var e,r,i,o=t.__transition,u=!0;if(o){for(i in n=null==n?null:n+"",o)(e=o[i]).name===n?(r=e.state>c&&e.state<_,e.state=v,e.timer.stop(),e.on.call(r?"interrupt":"cancel",t,t.__data__,e.index,e.group),delete o[i]):u=!1;u&&delete t.__transition}}function b(t,n,e){var r=t._id;return t.each(function(){var t=m(this,r);(t.value||(t.value={}))[n]=e.apply(this,arguments)}),function(t){return w(t,r).value[n]}}function x(t,n){var e;return("number"==typeof n?i.interpolateNumber:n instanceof o.color?i.interpolateRgb:(e=o.color(n))?(n=e,i.interpolateRgb):i.interpolateString)(t,n)}var A=n.selection.prototype.constructor;function E(t){return function(){this.style.removeProperty(t)}}var T=0;function N(t,n,e,r){this._groups=t,this._parents=n,this._name=e,this._id=r}function S(t){return n.selection().transition(t)}function q(){return++T}var C=n.selection.prototype;N.prototype=S.prototype={constructor:N,select:function(t){var e=this._name,r=this._id;"function"!=typeof t&&(t=n.selector(t));for(var i=this._groups,o=i.length,u=new Array(o),a=0;a=0&&(t=t.slice(0,n)),!t||"start"===t})}(n)?y:m;return function(){var u=o(this,t),a=u.on;a!==r&&(i=(r=a).copy()).on(n,e),u.on=i}}(e,t,n))},attr:function(t,e){var r=n.namespace(t),o="transform"===r?i.interpolateTransformSvg:x;return this.attrTween(t,"function"==typeof e?(r.local?function(t,n,e){var r,i,o;return function(){var u,a,s=e(this);if(null!=s)return(u=this.getAttributeNS(t.space,t.local))===(a=s+"")?null:u===r&&a===i?o:(i=a,o=n(r=u,s));this.removeAttributeNS(t.space,t.local)}}:function(t,n,e){var r,i,o;return function(){var u,a,s=e(this);if(null!=s)return(u=this.getAttribute(t))===(a=s+"")?null:u===r&&a===i?o:(i=a,o=n(r=u,s));this.removeAttribute(t)}})(r,o,b(this,"attr."+t,e)):null==e?(r.local?function(t){return function(){this.removeAttributeNS(t.space,t.local)}}:function(t){return function(){this.removeAttribute(t)}})(r):(r.local?function(t,n,e){var r,i,o=e+"";return function(){var u=this.getAttributeNS(t.space,t.local);return u===o?null:u===r?i:i=n(r=u,e)}}:function(t,n,e){var r,i,o=e+"";return function(){var u=this.getAttribute(t);return u===o?null:u===r?i:i=n(r=u,e)}})(r,o,e))},attrTween:function(t,e){var r="attr."+t;if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==e)return this.tween(r,null);if("function"!=typeof e)throw new Error;var i=n.namespace(t);return this.tween(r,(i.local?function(t,n){var e,r;function i(){var i=n.apply(this,arguments);return i!==r&&(e=(r=i)&&function(t,n){return function(e){this.setAttributeNS(t.space,t.local,n.call(this,e))}}(t,i)),e}return i._value=n,i}:function(t,n){var e,r;function i(){var i=n.apply(this,arguments);return i!==r&&(e=(r=i)&&function(t,n){return function(e){this.setAttribute(t,n.call(this,e))}}(t,i)),e}return i._value=n,i})(i,e))},style:function(t,e,r){var o="transform"==(t+="")?i.interpolateTransformCss:x;return null==e?this.styleTween(t,function(t,e){var r,i,o;return function(){var u=n.style(this,t),a=(this.style.removeProperty(t),n.style(this,t));return u===a?null:u===r&&a===i?o:o=e(r=u,i=a)}}(t,o)).on("end.style."+t,E(t)):"function"==typeof e?this.styleTween(t,function(t,e,r){var i,o,u;return function(){var a=n.style(this,t),s=r(this),l=s+"";return null==s&&(this.style.removeProperty(t),l=s=n.style(this,t)),a===l?null:a===i&&l===o?u:(o=l,u=e(i=a,s))}}(t,o,b(this,"style."+t,e))).each(function(t,n){var e,r,i,o,u="style."+n,a="end."+u;return function(){var s=m(this,t),l=s.on,f=null==s.value[u]?o||(o=E(n)):void 0;l===e&&i===f||(r=(e=l).copy()).on(a,i=f),s.on=r}}(this._id,t)):this.styleTween(t,function(t,e,r){var i,o,u=r+"";return function(){var a=n.style(this,t);return a===u?null:a===i?o:o=e(i=a,r)}}(t,o,e),r).on("end.style."+t,null)},styleTween:function(t,n,e){var r="style."+(t+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==n)return this.tween(r,null);if("function"!=typeof n)throw new Error;return this.tween(r,function(t,n,e){var r,i;function o(){var o=n.apply(this,arguments);return o!==i&&(r=(i=o)&&function(t,n,e){return function(r){this.style.setProperty(t,n.call(this,r),e)}}(t,o,e)),r}return o._value=n,o}(t,n,null==e?"":e))},text:function(t){return this.tween("text","function"==typeof t?function(t){return function(){var n=t(this);this.textContent=null==n?"":n}}(b(this,"text",t)):function(t){return function(){this.textContent=t}}(null==t?"":t+""))},textTween:function(t){var n="text";if(arguments.length<1)return(n=this.tween(n))&&n._value;if(null==t)return this.tween(n,null);if("function"!=typeof t)throw new Error;return this.tween(n,function(t){var n,e;function r(){var r=t.apply(this,arguments);return r!==e&&(n=(e=r)&&function(t){return function(n){this.textContent=t.call(this,n)}}(r)),n}return r._value=t,r}(t))},remove:function(){return this.on("end.remove",function(t){return function(){var n=this.parentNode;for(var e in this.__transition)if(+e!==t)return;n&&n.removeChild(this)}}(this._id))},tween:function(t,n){var e=this._id;if(t+="",arguments.length<2){for(var r,i=w(this.node(),e).tween,o=0,u=i.length;of&&e.name===n)return new N([[t]],O,n,+r);return null},t.interrupt=g,t.transition=S,Object.defineProperty(t,"__esModule",{value:!0})}); + +// https://d3js.org/d3-drag/ v1.2.5 Copyright 2019 Mike Bostock +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("d3-dispatch"),require("d3-selection")):"function"==typeof define&&define.amd?define(["exports","d3-dispatch","d3-selection"],e):e((t=t||self).d3=t.d3||{},t.d3,t.d3)}(this,function(t,e,n){"use strict";function o(){n.event.stopImmediatePropagation()}function i(){n.event.preventDefault(),n.event.stopImmediatePropagation()}function r(t){var e=t.document.documentElement,o=n.select(t).on("dragstart.drag",i,!0);"onselectstart"in e?o.on("selectstart.drag",i,!0):(e.__noselect=e.style.MozUserSelect,e.style.MozUserSelect="none")}function c(t,e){var o=t.document.documentElement,r=n.select(t).on("dragstart.drag",null);e&&(r.on("click.drag",i,!0),setTimeout(function(){r.on("click.drag",null)},0)),"onselectstart"in o?r.on("selectstart.drag",null):(o.style.MozUserSelect=o.__noselect,delete o.__noselect)}function u(t){return function(){return t}}function s(t,e,n,o,i,r,c,u,s,a){this.target=t,this.type=e,this.subject=n,this.identifier=o,this.active=i,this.x=r,this.y=c,this.dx=u,this.dy=s,this._=a}function a(){return!n.event.ctrlKey&&!n.event.button}function l(){return this.parentNode}function d(t){return null==t?{x:n.event.x,y:n.event.y}:t}function f(){return navigator.maxTouchPoints||"ontouchstart"in this}s.prototype.on=function(){var t=this._.on.apply(this._,arguments);return t===this._?this:t},t.drag=function(){var t,h,v,p,g=a,m=l,y=d,b=f,_={},w=e.dispatch("start","drag","end"),x=0,T=0;function j(t){t.on("mousedown.drag",k).filter(b).on("touchstart.drag",P).on("touchmove.drag",q).on("touchend.drag touchcancel.drag",z).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function k(){if(!p&&g.apply(this,arguments)){var e=D("mouse",m.apply(this,arguments),n.mouse,this,arguments);e&&(n.select(n.event.view).on("mousemove.drag",E,!0).on("mouseup.drag",M,!0),r(n.event.view),o(),v=!1,t=n.event.clientX,h=n.event.clientY,e("start"))}}function E(){if(i(),!v){var e=n.event.clientX-t,o=n.event.clientY-h;v=e*e+o*o>T}_.mouse("drag")}function M(){n.select(n.event.view).on("mousemove.drag mouseup.drag",null),c(n.event.view,v),i(),_.mouse("end")}function P(){if(g.apply(this,arguments)){var t,e,i=n.event.changedTouches,r=m.apply(this,arguments),c=i.length;for(t=0;to?(o+i)/2:Math.min(0,o)||Math.max(0,i),r>u?(u+r)/2:Math.min(0,u)||Math.max(0,r))}a.prototype=h.prototype,t.zoom=function(){var t,a,_=m,g=p,x=z,k=d,w=y,M=[0,1/0],T=[[-1/0,-1/0],[1/0,1/0]],b=250,Y=o.interpolateZoom,X=n.dispatch("start","zoom","end"),q=500,E=150,V=0;function B(t){t.property("__zoom",v).on("wheel.zoom",K).on("mousedown.zoom",A).on("dblclick.zoom",H).filter(w).on("touchstart.zoom",N).on("touchmove.zoom",O).on("touchend.zoom touchcancel.zoom",W).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function D(t,n){return(n=Math.max(M[0],Math.min(M[1],n)))===t.k?t:new h(n,t.x,t.y)}function P(t,n,e){var o=n[0]-e[0]*t.k,i=n[1]-e[1]*t.k;return o===t.x&&i===t.y?t:new h(t.k,o,i)}function I(t){return[(+t[0][0]+ +t[1][0])/2,(+t[0][1]+ +t[1][1])/2]}function S(t,n,e){t.on("start.zoom",function(){j(this,arguments).start()}).on("interrupt.zoom end.zoom",function(){j(this,arguments).end()}).tween("zoom",function(){var t=this,o=arguments,i=j(t,o),u=g.apply(t,o),r=null==e?I(u):"function"==typeof e?e.apply(t,o):e,s=Math.max(u[1][0]-u[0][0],u[1][1]-u[0][1]),c=t.__zoom,a="function"==typeof n?n.apply(t,o):n,f=Y(c.invert(r).concat(s/c.k),a.invert(r).concat(s/a.k));return function(t){if(1===t)t=a;else{var n=f(t),e=s/n[2];t=new h(e,r[0]-n[0]*e,r[1]-n[1]*e)}i.zoom(null,t)}})}function j(t,n,e){return!e&&t.__zooming||new G(t,n)}function G(t,n){this.that=t,this.args=n,this.active=0,this.extent=g.apply(t,n),this.taps=0}function K(){if(_.apply(this,arguments)){var t=j(this,arguments),n=this.__zoom,e=Math.max(M[0],Math.min(M[1],n.k*Math.pow(2,k.apply(this,arguments)))),o=i.mouse(this);if(t.wheel)t.mouse[0][0]===o[0]&&t.mouse[0][1]===o[1]||(t.mouse[1]=n.invert(t.mouse[0]=o)),clearTimeout(t.wheel);else{if(n.k===e)return;t.mouse=[o,n.invert(o)],u.interrupt(this),t.start()}l(),t.wheel=setTimeout(function(){t.wheel=null,t.end()},E),t.zoom("mouse",x(P(D(n,e),t.mouse[0],t.mouse[1]),t.extent,T))}}function A(){if(!a&&_.apply(this,arguments)){var t=j(this,arguments,!0),n=i.select(i.event.view).on("mousemove.zoom",function(){if(l(),!t.moved){var n=i.event.clientX-r,e=i.event.clientY-s;t.moved=n*n+e*e>V}t.zoom("mouse",x(P(t.that.__zoom,t.mouse[0]=i.mouse(t.that),t.mouse[1]),t.extent,T))},!0).on("mouseup.zoom",function(){n.on("mousemove.zoom mouseup.zoom",null),e.dragEnable(i.event.view,t.moved),l(),t.end()},!0),o=i.mouse(this),r=i.event.clientX,s=i.event.clientY;e.dragDisable(i.event.view),f(),t.mouse=[o,this.__zoom.invert(o)],u.interrupt(this),t.start()}}function H(){if(_.apply(this,arguments)){var t=this.__zoom,n=i.mouse(this),e=t.invert(n),o=t.k*(i.event.shiftKey?.5:2),u=x(P(D(t,o),n,e),g.apply(this,arguments),T);l(),b>0?i.select(this).transition().duration(b).call(S,u,n):i.select(this).call(B.transform,u)}}function N(){if(_.apply(this,arguments)){var n,e,o,r,s=i.event.touches,h=s.length,c=j(this,arguments,i.event.changedTouches.length===h);for(f(),e=0;e=r?(o=c,(u+=1)=r?(o=c,(u+=1)>1;return["sum(",r(t.slice(0,n)),",",r(t.slice(n)),")"].join("")}function s(t){if(2===t.length)return[["sum(prod(",t[0][0],",",t[1][1],"),prod(-",t[0][1],",",t[1][0],"))"].join("")];for(var o=[],a=0;a0){if(a<=0)return s;r=o+a}else{if(!(o<0))return s;if(a>=0)return s;r=-(o+a)}var i=g*r;return s>=i||s<=-i?s:m(t,n,e)},function(t,n,e,r){var o=t[0]-r[0],a=n[0]-r[0],s=e[0]-r[0],i=t[1]-r[1],u=n[1]-r[1],l=e[1]-r[1],f=t[2]-r[2],c=n[2]-r[2],h=e[2]-r[2],d=a*l,p=s*u,v=s*i,g=o*l,m=o*u,M=a*i,y=f*(d-p)+c*(v-g)+h*(m-M),w=(Math.abs(d)+Math.abs(p))*Math.abs(f)+(Math.abs(v)+Math.abs(g))*Math.abs(c)+(Math.abs(m)+Math.abs(M))*Math.abs(h),x=_*w;return y>x||-y>x?y:b(t,n,e,r)}];!function(){for(;M.length<=5;)M.push(l(M.length));for(var n=[],e=["slow"],r=0;r<=5;++r)n.push("a"+r),e.push("o"+r);var o=["function getOrientation(",n.join(),"){switch(arguments.length){case 0:case 1:return 0;"];for(r=2;r<=5;++r)o.push("case ",r,":return o",r,"(",n.slice(0,r).join(),");");o.push("}var s=new Array(arguments.length);for(var i=0;i0;){var _=(l+a-1)%a;if((M=t[_])[1]!==o)break;var m=M[0];v=Math.min(v,m),g=Math.max(g,m),l=_}if(0===l)return v<=r&&r<=g?0:1;i=l+1}for(var b=t[(l+a-1)%a][1];u+1-1&&(i[n]=e),t):i},t.targetArea=function(e){return arguments.length?(n=e,t):n},t},Object.defineProperty(t,"__esModule",{value:!0})})); \ No newline at end of file diff --git a/content/blog/ggplot2-styling/figs/aspect_ratio-1.png b/content/blog/ggplot2-styling/figs/aspect_ratio-1.png new file mode 100644 index 000000000..4798ab518 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/aspect_ratio-1.png differ diff --git a/content/blog/ggplot2-styling/figs/axis_local_theme-1.png b/content/blog/ggplot2-styling/figs/axis_local_theme-1.png new file mode 100644 index 000000000..560e280c8 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/axis_local_theme-1.png differ diff --git a/content/blog/ggplot2-styling/figs/complete_base_size-1.png b/content/blog/ggplot2-styling/figs/complete_base_size-1.png new file mode 100644 index 000000000..4be24f606 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/complete_base_size-1.png differ diff --git a/content/blog/ggplot2-styling/figs/complete_bw-1.png b/content/blog/ggplot2-styling/figs/complete_bw-1.png new file mode 100644 index 000000000..99068d0b0 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/complete_bw-1.png differ diff --git a/content/blog/ggplot2-styling/figs/complete_classic-1.png b/content/blog/ggplot2-styling/figs/complete_classic-1.png new file mode 100644 index 000000000..4ff8f0027 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/complete_classic-1.png differ diff --git a/content/blog/ggplot2-styling/figs/complete_cowplot-1.png b/content/blog/ggplot2-styling/figs/complete_cowplot-1.png new file mode 100644 index 000000000..95819bd91 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/complete_cowplot-1.png differ diff --git a/content/blog/ggplot2-styling/figs/complete_dark-1.png b/content/blog/ggplot2-styling/figs/complete_dark-1.png new file mode 100644 index 000000000..ba82ace9b Binary files /dev/null and b/content/blog/ggplot2-styling/figs/complete_dark-1.png differ diff --git a/content/blog/ggplot2-styling/figs/complete_font_family-1.png b/content/blog/ggplot2-styling/figs/complete_font_family-1.png new file mode 100644 index 000000000..5dc0b93a5 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/complete_font_family-1.png differ diff --git a/content/blog/ggplot2-styling/figs/complete_ggthemes-1.png b/content/blog/ggplot2-styling/figs/complete_ggthemes-1.png new file mode 100644 index 000000000..27de77e74 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/complete_ggthemes-1.png differ diff --git a/content/blog/ggplot2-styling/figs/complete_grey-1.png b/content/blog/ggplot2-styling/figs/complete_grey-1.png new file mode 100644 index 000000000..b379aa9a1 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/complete_grey-1.png differ diff --git a/content/blog/ggplot2-styling/figs/complete_ink_paper-1.png b/content/blog/ggplot2-styling/figs/complete_ink_paper-1.png new file mode 100644 index 000000000..df8ef5d5f Binary files /dev/null and b/content/blog/ggplot2-styling/figs/complete_ink_paper-1.png differ diff --git a/content/blog/ggplot2-styling/figs/complete_light-1.png b/content/blog/ggplot2-styling/figs/complete_light-1.png new file mode 100644 index 000000000..8b431b93c Binary files /dev/null and b/content/blog/ggplot2-styling/figs/complete_light-1.png differ diff --git a/content/blog/ggplot2-styling/figs/complete_linedraw-1.png b/content/blog/ggplot2-styling/figs/complete_linedraw-1.png new file mode 100644 index 000000000..03fa0c288 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/complete_linedraw-1.png differ diff --git a/content/blog/ggplot2-styling/figs/complete_minimal-1.png b/content/blog/ggplot2-styling/figs/complete_minimal-1.png new file mode 100644 index 000000000..b3f638eeb Binary files /dev/null and b/content/blog/ggplot2-styling/figs/complete_minimal-1.png differ diff --git a/content/blog/ggplot2-styling/figs/complete_test-1.png b/content/blog/ggplot2-styling/figs/complete_test-1.png new file mode 100644 index 000000000..3d815f6e1 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/complete_test-1.png differ diff --git a/content/blog/ggplot2-styling/figs/complete_tvthemes-1.png b/content/blog/ggplot2-styling/figs/complete_tvthemes-1.png new file mode 100644 index 000000000..a6040dcad Binary files /dev/null and b/content/blog/ggplot2-styling/figs/complete_tvthemes-1.png differ diff --git a/content/blog/ggplot2-styling/figs/complete_void-1.png b/content/blog/ggplot2-styling/figs/complete_void-1.png new file mode 100644 index 000000000..38a03fa9d Binary files /dev/null and b/content/blog/ggplot2-styling/figs/complete_void-1.png differ diff --git a/content/blog/ggplot2-styling/figs/element_marquee-1.png b/content/blog/ggplot2-styling/figs/element_marquee-1.png new file mode 100644 index 000000000..40d5ae2e5 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/element_marquee-1.png differ diff --git a/content/blog/ggplot2-styling/figs/example_complete-1.png b/content/blog/ggplot2-styling/figs/example_complete-1.png new file mode 100644 index 000000000..b3f638eeb Binary files /dev/null and b/content/blog/ggplot2-styling/figs/example_complete-1.png differ diff --git a/content/blog/ggplot2-styling/figs/extension_elements-1.png b/content/blog/ggplot2-styling/figs/extension_elements-1.png new file mode 100644 index 000000000..45afaafaf Binary files /dev/null and b/content/blog/ggplot2-styling/figs/extension_elements-1.png differ diff --git a/content/blog/ggplot2-styling/figs/fonts-1.png b/content/blog/ggplot2-styling/figs/fonts-1.png new file mode 100644 index 000000000..ca7688807 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/fonts-1.png differ diff --git a/content/blog/ggplot2-styling/figs/layer_aesthetic-1.png b/content/blog/ggplot2-styling/figs/layer_aesthetic-1.png new file mode 100644 index 000000000..8feba8e8a Binary files /dev/null and b/content/blog/ggplot2-styling/figs/layer_aesthetic-1.png differ diff --git a/content/blog/ggplot2-styling/figs/layer_borderline-1.png b/content/blog/ggplot2-styling/figs/layer_borderline-1.png new file mode 100644 index 000000000..f7e279469 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/layer_borderline-1.png differ diff --git a/content/blog/ggplot2-styling/figs/layer_colour_fill-1.png b/content/blog/ggplot2-styling/figs/layer_colour_fill-1.png new file mode 100644 index 000000000..e2ca84f21 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/layer_colour_fill-1.png differ diff --git a/content/blog/ggplot2-styling/figs/layer_granular-1.png b/content/blog/ggplot2-styling/figs/layer_granular-1.png new file mode 100644 index 000000000..dcb738796 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/layer_granular-1.png differ diff --git a/content/blog/ggplot2-styling/figs/layer_ink_paper-1.png b/content/blog/ggplot2-styling/figs/layer_ink_paper-1.png new file mode 100644 index 000000000..eb362f1c9 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/layer_ink_paper-1.png differ diff --git a/content/blog/ggplot2-styling/figs/layer_pointtext-1.png b/content/blog/ggplot2-styling/figs/layer_pointtext-1.png new file mode 100644 index 000000000..146e4def8 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/layer_pointtext-1.png differ diff --git a/content/blog/ggplot2-styling/figs/palettes-1.png b/content/blog/ggplot2-styling/figs/palettes-1.png new file mode 100644 index 000000000..9ce7668da Binary files /dev/null and b/content/blog/ggplot2-styling/figs/palettes-1.png differ diff --git a/content/blog/ggplot2-styling/figs/part_theme_barchart-1.png b/content/blog/ggplot2-styling/figs/part_theme_barchart-1.png new file mode 100644 index 000000000..1eec38caf Binary files /dev/null and b/content/blog/ggplot2-styling/figs/part_theme_barchart-1.png differ diff --git a/content/blog/ggplot2-styling/figs/part_theme_bottom_colourbar-1.png b/content/blog/ggplot2-styling/figs/part_theme_bottom_colourbar-1.png new file mode 100644 index 000000000..7c69f11c2 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/part_theme_bottom_colourbar-1.png differ diff --git a/content/blog/ggplot2-styling/figs/part_theme_upper_legend-1.png b/content/blog/ggplot2-styling/figs/part_theme_upper_legend-1.png new file mode 100644 index 000000000..a2014f108 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/part_theme_upper_legend-1.png differ diff --git a/content/blog/ggplot2-styling/figs/pattern_fill-1.png b/content/blog/ggplot2-styling/figs/pattern_fill-1.png new file mode 100644 index 000000000..869294633 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/pattern_fill-1.png differ diff --git a/content/blog/ggplot2-styling/figs/red_axis-1.png b/content/blog/ggplot2-styling/figs/red_axis-1.png new file mode 100644 index 000000000..1e42e755e Binary files /dev/null and b/content/blog/ggplot2-styling/figs/red_axis-1.png differ diff --git a/content/blog/ggplot2-styling/figs/root_leaves-1.png b/content/blog/ggplot2-styling/figs/root_leaves-1.png new file mode 100644 index 000000000..992755735 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/root_leaves-1.png differ diff --git a/content/blog/ggplot2-styling/figs/stretchy_colourbar-1.png b/content/blog/ggplot2-styling/figs/stretchy_colourbar-1.png new file mode 100644 index 000000000..0045a021c Binary files /dev/null and b/content/blog/ggplot2-styling/figs/stretchy_colourbar-1.png differ diff --git a/content/blog/ggplot2-styling/figs/sub_axis-1.png b/content/blog/ggplot2-styling/figs/sub_axis-1.png new file mode 100644 index 000000000..c1a5176f8 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/sub_axis-1.png differ diff --git a/content/blog/ggplot2-styling/figs/sub_axis_positions-1.png b/content/blog/ggplot2-styling/figs/sub_axis_positions-1.png new file mode 100644 index 000000000..a5b9331e7 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/sub_axis_positions-1.png differ diff --git a/content/blog/ggplot2-styling/figs/sub_axis_xy-1.png b/content/blog/ggplot2-styling/figs/sub_axis_xy-1.png new file mode 100644 index 000000000..b6a3ed1ef Binary files /dev/null and b/content/blog/ggplot2-styling/figs/sub_axis_xy-1.png differ diff --git a/content/blog/ggplot2-styling/figs/sub_legend_binned-1.png b/content/blog/ggplot2-styling/figs/sub_legend_binned-1.png new file mode 100644 index 000000000..3a9f2b964 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/sub_legend_binned-1.png differ diff --git a/content/blog/ggplot2-styling/figs/sub_legend_colourbar-1.png b/content/blog/ggplot2-styling/figs/sub_legend_colourbar-1.png new file mode 100644 index 000000000..87231a811 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/sub_legend_colourbar-1.png differ diff --git a/content/blog/ggplot2-styling/figs/sub_legend_general-1.png b/content/blog/ggplot2-styling/figs/sub_legend_general-1.png new file mode 100644 index 000000000..9e4e2874c Binary files /dev/null and b/content/blog/ggplot2-styling/figs/sub_legend_general-1.png differ diff --git a/content/blog/ggplot2-styling/figs/sub_legend_guidebox-1.png b/content/blog/ggplot2-styling/figs/sub_legend_guidebox-1.png new file mode 100644 index 000000000..feee557ba Binary files /dev/null and b/content/blog/ggplot2-styling/figs/sub_legend_guidebox-1.png differ diff --git a/content/blog/ggplot2-styling/figs/sub_legend_guidebox_position-1.png b/content/blog/ggplot2-styling/figs/sub_legend_guidebox_position-1.png new file mode 100644 index 000000000..2fe381aac Binary files /dev/null and b/content/blog/ggplot2-styling/figs/sub_legend_guidebox_position-1.png differ diff --git a/content/blog/ggplot2-styling/figs/sub_legend_legend-1.png b/content/blog/ggplot2-styling/figs/sub_legend_legend-1.png new file mode 100644 index 000000000..f9a648d2c Binary files /dev/null and b/content/blog/ggplot2-styling/figs/sub_legend_legend-1.png differ diff --git a/content/blog/ggplot2-styling/figs/sub_panel-1.png b/content/blog/ggplot2-styling/figs/sub_panel-1.png new file mode 100644 index 000000000..433fd7b78 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/sub_panel-1.png differ diff --git a/content/blog/ggplot2-styling/figs/sub_panel_border_background-1.png b/content/blog/ggplot2-styling/figs/sub_panel_border_background-1.png new file mode 100644 index 000000000..aaaa2ba56 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/sub_panel_border_background-1.png differ diff --git a/content/blog/ggplot2-styling/figs/sub_panel_size-1.png b/content/blog/ggplot2-styling/figs/sub_panel_size-1.png new file mode 100644 index 000000000..e7810b347 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/sub_panel_size-1.png differ diff --git a/content/blog/ggplot2-styling/figs/sub_plot-1.png b/content/blog/ggplot2-styling/figs/sub_plot-1.png new file mode 100644 index 000000000..0f64f44e1 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/sub_plot-1.png differ diff --git a/content/blog/ggplot2-styling/figs/sub_strip-1.png b/content/blog/ggplot2-styling/figs/sub_strip-1.png new file mode 100644 index 000000000..260e637f1 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/sub_strip-1.png differ diff --git a/content/blog/ggplot2-styling/figs/theme_adding_parts-1.png b/content/blog/ggplot2-styling/figs/theme_adding_parts-1.png new file mode 100644 index 000000000..8d74c9ec3 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/theme_adding_parts-1.png differ diff --git a/content/blog/ggplot2-styling/figs/theme_caching-1.png b/content/blog/ggplot2-styling/figs/theme_caching-1.png new file mode 100644 index 000000000..4656029ac Binary files /dev/null and b/content/blog/ggplot2-styling/figs/theme_caching-1.png differ diff --git a/content/blog/ggplot2-styling/figs/theme_set-1.png b/content/blog/ggplot2-styling/figs/theme_set-1.png new file mode 100644 index 000000000..86025a786 Binary files /dev/null and b/content/blog/ggplot2-styling/figs/theme_set-1.png differ diff --git a/content/blog/ggplot2-styling/flatbush-4.4.0/flatbush.min.js b/content/blog/ggplot2-styling/flatbush-4.4.0/flatbush.min.js new file mode 100644 index 000000000..9b4855437 --- /dev/null +++ b/content/blog/ggplot2-styling/flatbush-4.4.0/flatbush.min.js @@ -0,0 +1 @@ +!function(t,s){"object"==typeof exports&&"undefined"!=typeof module?module.exports=s():"function"==typeof define&&define.amd?define(s):(t="undefined"!=typeof globalThis?globalThis:t||self).Flatbush=s()}(this,(function(){"use strict";class t{constructor(){this.ids=[],this.values=[],this.length=0}clear(){this.length=0}push(t,s){let i=this.length++;for(;0>1,h=this.values[e];if(h<=s)break;this.ids[i]=this.ids[e],this.values[i]=h,i=e}this.ids[i]=t,this.values[i]=s}pop(){if(0!==this.length){var t=this.ids[0];if(this.length--,0>1;let t=0;for(;t=i)break;this.ids[t]=e,this.values[t]=n,t=s}this.ids[t]=s,this.values[t]=i}return t}}peek(){if(0!==this.length)return this.ids[0]}peekValue(){if(0!==this.length)return this.values[0]}shrink(){this.ids.length=this.values.length=this.length}}const s=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];function i(t,s,i){return t>1;s[h]>t?e=h:i=1+h}return s[i]}function h(t,s,i,e,h){var r=t[e],n=(t[e]=t[h],t[h]=r,r=4*h,s[t=4*e]),a=s[1+t],o=s[2+t],l=s[3+t];s[t]=s[r],s[1+t]=s[1+r],s[2+t]=s[2+r],s[3+t]=s[3+r],s[r]=n,s[1+r]=a,s[2+r]=o,s[3+r]=l,t=i[e],i[e]=i[h],i[h]=t}return class r{static from(t,i=0){if(i%8!=0)throw new Error("byteOffset must be 8-byte aligned.");if(!t||void 0===t.byteLength||t.buffer)throw new Error("Data must be an instance of ArrayBuffer or SharedArrayBuffer.");var e,[h,n]=new Uint8Array(t,i+0,2);if(251!==h)throw new Error("Data does not appear to be in a Flatbush format.");if(3!=(h=n>>4))throw new Error(`Got v${h} data when expected v3.`);if(h=s[15&n])return[n]=new Uint16Array(t,i+2,1),[e]=new Uint32Array(t,i+4,1),new r(e,n,h,void 0,t,i);throw new Error("Unrecognized array type.")}constructor(i,e=16,h=Float64Array,r=ArrayBuffer,n,a=0){if(void 0===i)throw new Error("Missing required argument: numItems.");if(isNaN(i)||i<=0)throw new Error(`Unexpected numItems value: ${i}.`);this.numItems=+i,this.nodeSize=Math.min(Math.max(+e,2),65535),this.byteOffset=a;let o=i,l=o;for(this._levelBounds=[4*o];o=Math.ceil(o/this.nodeSize),l+=o,this._levelBounds.push(4*l),1!==o;);this.ArrayType=h,this.IndexArrayType=l<16384?Uint16Array:Uint32Array;var d=s.indexOf(this.ArrayType),f=4*l*this.ArrayType.BYTES_PER_ELEMENT;if(d<0)throw new Error(`Unexpected typed array class: ${h}.`);n&&void 0!==n.byteLength&&!n.buffer?(this.data=n,this._boxes=new this.ArrayType(this.data,a+8,4*l),this._indices=new this.IndexArrayType(this.data,a+8+f,l),this._pos=4*l,this.minX=this._boxes[this._pos-4],this.minY=this._boxes[this._pos-3],this.maxX=this._boxes[this._pos-2],this.maxY=this._boxes[this._pos-1]):(this.data=new r(8+f+l*this.IndexArrayType.BYTES_PER_ELEMENT),this._boxes=new this.ArrayType(this.data,8,4*l),this._indices=new this.IndexArrayType(this.data,8+f,l),this._pos=0,this.minX=1/0,this.minY=1/0,this.maxX=-1/0,this.maxY=-1/0,new Uint8Array(this.data,0,2).set([251,48+d]),new Uint16Array(this.data,2,1)[0]=e,new Uint32Array(this.data,4,1)[0]=i),this._queue=new t}add(t,s,i=t,e=s){var h=this._pos>>2,r=this._boxes;return this._indices[h]=h,r[this._pos++]=t,r[this._pos++]=s,r[this._pos++]=i,r[this._pos++]=e,tthis.maxX&&(this.maxX=i),e>this.maxY&&(this.maxY=e),h}finish(){if(this._pos>>2!==this.numItems)throw new Error(`Added ${this._pos>>2} items when expected ${this.numItems}.`);var t=this._boxes;if(this.numItems<=this.nodeSize)t[this._pos++]=this.minX,t[this._pos++]=this.minY,t[this._pos++]=this.maxX,t[this._pos++]=this.maxY;else{var s,i,e,r,n,a,o=this.maxX-this.minX||1,l=this.maxY-this.minY||1,d=new Uint32Array(this.numItems);for(let h=0,_=0;h>1^u,n=(s=65535^(f|p))>>1^(m=65535^u)&(i=f&(65535^p))>>1^s,a=u&s>>1^i>>1^i,u=e=u|m>>1,r=e&(m=r)>>2^m&(e^m)>>2,n^=e&(s=n)>>2^m&a>>2,a^=m&s>>2^(e^m)&(i=a)>>2,u=e=e&(u=e)>>2^m&m>>2,n^=e&(s=n)>>4^(m=r)&a>>4,((1431655765&((r=858993459&((r=252645135&((r=16711935&((r=(a=(a^=m&s>>4^(e^m)&(i=a)>>4)^(r=e&m>>4^m&(e^m)>>4)&n>>8^((u=e=e&(u=e)>>4^m&m>>4)^r)&(i=a)>>8)^a>>1|65535^((e=f^p)|(u=(n^=u&(s=n)>>8^(m=r)&i>>8)^n>>1)))|r<<8))|r<<4))|r<<2))|r<<1))<<1|(e=1431655765&((e=858993459&((e=252645135&((e=16711935&(e|e<<8))|e<<4))|e<<2))|e<<1)))>>>0)}!function t(s,i,e,r,n,a){if(!(Math.floor(r/a)>=Math.floor(n/a))){const o=s[r+n>>1];let l=r-1,d=n+1;for(;;){for(;l++,s[l]o;);if(l>=d)break;h(s,i,e,l,d)}t(s,i,e,r,d,a),t(s,i,e,d+1,n,a)}}(d,t,this._indices,0,this.numItems-1,this.nodeSize);for(let s=0,i=0;s>2]=y,t[this._pos++]=s,t[this._pos++]=e,t[this._pos++]=h,t[this._pos++]=r}}}search(t,s,i,h,r){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");let n=this._boxes.length-4;for(var a=[],o=[];void 0!==n;){var l,d=Math.min(n+4*this.nodeSize,e(n,this._levelBounds));for(let e=n;ethis._boxes[e+2]||s>this._boxes[e+3]||(l=0|this._indices[e>>2],n>=4*this.numItems?a.push(l):void 0!==r&&!r(l)||o.push(l));n=a.pop()}return o}neighbors(t,s,h=1/0,r=1/0,n){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");let a=this._boxes.length-4;var o=this._queue,l=[],d=r*r;t:for(;void 0!==a;){var f=Math.min(a+4*this.nodeSize,e(a,this._levelBounds));for(let e=a;e>2],p=i(t,this._boxes[e],this._boxes[e+2]),m=i(s,this._boxes[e+1],this._boxes[e+3]);d<(p=p*p+m*m)||(a>=4*this.numItems?o.push(u<<1,p):void 0!==n&&!n(u)||o.push(1+(u<<1),p))}for(;o.length&&1&o.peek();){if(d>1),l.length===h)break t}a=o.length?o.pop()>>1:void 0}return o.clear(),l}}})); \ No newline at end of file diff --git a/content/blog/ggplot2-styling/ggiraphjs-0.8.10/ggiraphjs.min.css b/content/blog/ggplot2-styling/ggiraphjs-0.8.10/ggiraphjs.min.css new file mode 100644 index 000000000..31815845a --- /dev/null +++ b/content/blog/ggplot2-styling/ggiraphjs-0.8.10/ggiraphjs.min.css @@ -0,0 +1 @@ +.girafe,.girafe_container_std{margin-left:auto;margin-right:auto}.girafe_container_std{position:relative;text-align:center}.girafe_container_ie{height:0}.girafe_svg_ie{left:0;position:absolute;top:0}.ggiraph-toolbar{background-color:#fff;background-color:hsla(0,0%,100%,.3);border-radius:5px;padding:2px}.ggiraph-toolbar-floating{opacity:0;position:absolute}.ggiraph-toolbar-bottom,.ggiraph-toolbar-top{text-align:center}.ggiraph-toolbar-bottomleft,.ggiraph-toolbar-topleft{text-align:left}.ggiraph-toolbar-bottomright,.ggiraph-toolbar-topright{text-align:right}.ggiraph-toolbar-floating-top{left:0;right:0;top:3px}.ggiraph-toolbar-floating-topleft{left:3px;top:3px}.ggiraph-toolbar-floating-topright{right:3px;top:3px}.ggiraph-toolbar-floating-bottom{bottom:3px;left:0;right:0}.ggiraph-toolbar-floating-bottomleft{bottom:3px;left:3px}.ggiraph-toolbar-floating-bottomright{bottom:3px;right:3px}.ggiraph-toolbar-block{display:inline-block}.ggiraph-toolbar-block:not(:last-child){margin-right:10px}.ggiraph-toolbar-icon{border:0;cursor:pointer;display:inline-block;height:15pt;margin:0;padding:0;width:15pt}.ggiraph-toolbar-icon:not(:last-child){margin-right:3px}.ggiraph-toolbar-icon svg{pointer-events:none}.ggiraph-toolbar-icon.drop{stroke:#e30c37;fill:#e30c37}.ggiraph-toolbar-icon.drop:hover{stroke:#333;fill:#333}.ggiraph-toolbar-icon.neutral{stroke:#069;fill:#069}.ggiraph-toolbar-icon.neutral:hover{stroke:#333;fill:#333}.ggiraph-svg .lasso path{stroke:#505050;stroke-width:1px}.ggiraph-svg .lasso .drawn{fill-opacity:.05}.ggiraph-svg .lasso .loop_close{fill:none;stroke-dasharray:4,4}.ggiraph-svg .lasso .origin{fill:#333;fill-opacity:.5}.ggiraph-svg .dragrect rect{stroke:#505050;stroke-width:1px;fill-opacity:.05}.ggiraph-svg .ggiraph-svg-rootg circle:not([id]),.ggiraph-svg .ggiraph-svg-rootg image:not([id]),.ggiraph-svg .ggiraph-svg-rootg line:not([id]),.ggiraph-svg .ggiraph-svg-rootg path:not([id]),.ggiraph-svg .ggiraph-svg-rootg polygon:not([id]),.ggiraph-svg .ggiraph-svg-rootg polyline:not([id]),.ggiraph-svg .ggiraph-svg-rootg rect:not([id]):not(.ggiraph-svg-bg),.ggiraph-svg .ggiraph-svg-rootg text:not([id]){pointer-events:none}.ggiraph-svg .ggiraph-svg-rootg [id]{pointer-events:all} \ No newline at end of file diff --git a/content/blog/ggplot2-styling/ggiraphjs-0.8.10/ggiraphjs.min.js b/content/blog/ggplot2-styling/ggiraphjs-0.8.10/ggiraphjs.min.js new file mode 100644 index 000000000..3681b0c39 --- /dev/null +++ b/content/blog/ggplot2-styling/ggiraphjs-0.8.10/ggiraphjs.min.js @@ -0,0 +1 @@ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("d3"),require("Flatbush")):"function"==typeof define&&define.amd?define(["d3","Flatbush"],e):"object"==typeof exports?exports.ggiraphjs=e(require("d3"),require("Flatbush")):t.ggiraphjs=e(t.d3,t.Flatbush)}(self,((t,e)=>(()=>{"use strict";var r={349:t=>{t.exports=e},3893:e=>{e.exports=t},9306:(t,e,r)=>{var n=r(4901),i=r(6823),o=TypeError;t.exports=function(t){if(n(t))return t;throw new o(i(t)+" is not a function")}},5548:(t,e,r)=>{var n=r(3517),i=r(6823),o=TypeError;t.exports=function(t){if(n(t))return t;throw new o(i(t)+" is not a constructor")}},3506:(t,e,r)=>{var n=r(3925),i=String,o=TypeError;t.exports=function(t){if(n(t))return t;throw new o("Can't set "+i(t)+" as a prototype")}},6469:(t,e,r)=>{var n=r(8227),i=r(2360),o=r(4913).f,a=n("unscopables"),s=Array.prototype;void 0===s[a]&&o(s,a,{configurable:!0,value:i(null)}),t.exports=function(t){s[a][t]=!0}},7829:(t,e,r)=>{var n=r(8183).charAt;t.exports=function(t,e,r){return e+(r?n(t,e).length:1)}},679:(t,e,r)=>{var n=r(1625),i=TypeError;t.exports=function(t,e){if(n(e,t))return t;throw new i("Incorrect invocation")}},8551:(t,e,r)=>{var n=r(34),i=String,o=TypeError;t.exports=function(t){if(n(t))return t;throw new o(i(t)+" is not an object")}},7811:t=>{t.exports="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof DataView},5652:(t,e,r)=>{var n=r(9039);t.exports=n((function(){if("function"==typeof ArrayBuffer){var t=new ArrayBuffer(8);Object.isExtensible(t)&&Object.defineProperty(t,"a",{value:8})}}))},4644:(t,e,r)=>{var n,i,o,a=r(7811),s=r(3724),u=r(4475),c=r(4901),f=r(34),l=r(9297),h=r(6955),p=r(6823),y=r(6699),v=r(6840),d=r(2106),g=r(1625),m=r(2787),x=r(2967),b=r(8227),w=r(3392),S=r(1181),E=S.enforce,A=S.get,O=u.Int8Array,I=O&&O.prototype,T=u.Uint8ClampedArray,k=T&&T.prototype,M=O&&m(O),_=I&&m(I),P=Object.prototype,N=u.TypeError,j=b("toStringTag"),R=w("TYPED_ARRAY_TAG"),V="TypedArrayConstructor",D=a&&!!x&&"Opera"!==h(u.opera),C=!1,F={Int8Array:1,Uint8Array:1,Uint8ClampedArray:1,Int16Array:2,Uint16Array:2,Int32Array:4,Uint32Array:4,Float32Array:4,Float64Array:8},z={BigInt64Array:8,BigUint64Array:8},L=function(t){var e=m(t);if(f(e)){var r=A(e);return r&&l(r,V)?r[V]:L(e)}},B=function(t){if(!f(t))return!1;var e=h(t);return l(F,e)||l(z,e)};for(n in F)(o=(i=u[n])&&i.prototype)?E(o)[V]=i:D=!1;for(n in z)(o=(i=u[n])&&i.prototype)&&(E(o)[V]=i);if((!D||!c(M)||M===Function.prototype)&&(M=function(){throw new N("Incorrect invocation")},D))for(n in F)u[n]&&x(u[n],M);if((!D||!_||_===P)&&(_=M.prototype,D))for(n in F)u[n]&&x(u[n].prototype,_);if(D&&m(k)!==_&&x(k,_),s&&!l(_,j))for(n in C=!0,d(_,j,{configurable:!0,get:function(){return f(this)?this[R]:void 0}}),F)u[n]&&y(u[n],R,n);t.exports={NATIVE_ARRAY_BUFFER_VIEWS:D,TYPED_ARRAY_TAG:C&&R,aTypedArray:function(t){if(B(t))return t;throw new N("Target is not a typed array")},aTypedArrayConstructor:function(t){if(c(t)&&(!x||g(M,t)))return t;throw new N(p(t)+" is not a typed array constructor")},exportTypedArrayMethod:function(t,e,r,n){if(s){if(r)for(var i in F){var o=u[i];if(o&&l(o.prototype,t))try{delete o.prototype[t]}catch(r){try{o.prototype[t]=e}catch(t){}}}_[t]&&!r||v(_,t,r?e:D&&I[t]||e,n)}},exportTypedArrayStaticMethod:function(t,e,r){var n,i;if(s){if(x){if(r)for(n in F)if((i=u[n])&&l(i,t))try{delete i[t]}catch(t){}if(M[t]&&!r)return;try{return v(M,t,r?e:D&&M[t]||e)}catch(t){}}for(n in F)!(i=u[n])||i[t]&&!r||v(i,t,e)}},getTypedArrayConstructor:L,isView:function(t){if(!f(t))return!1;var e=h(t);return"DataView"===e||l(F,e)||l(z,e)},isTypedArray:B,TypedArray:M,TypedArrayPrototype:_}},6346:(t,e,r)=>{var n=r(4475),i=r(9504),o=r(3724),a=r(7811),s=r(350),u=r(6699),c=r(2106),f=r(6279),l=r(9039),h=r(679),p=r(1291),y=r(8014),v=r(7696),d=r(5617),g=r(8490),m=r(2787),x=r(2967),b=r(4373),w=r(7680),S=r(3167),E=r(7740),A=r(687),O=r(1181),I=s.PROPER,T=s.CONFIGURABLE,k="ArrayBuffer",M="DataView",_="prototype",P="Wrong index",N=O.getterFor(k),j=O.getterFor(M),R=O.set,V=n[k],D=V,C=D&&D[_],F=n[M],z=F&&F[_],L=Object.prototype,B=n.Array,G=n.RangeError,U=i(b),H=i([].reverse),W=g.pack,Y=g.unpack,$=function(t){return[255&t]},q=function(t){return[255&t,t>>8&255]},K=function(t){return[255&t,t>>8&255,t>>16&255,t>>24&255]},X=function(t){return t[3]<<24|t[2]<<16|t[1]<<8|t[0]},J=function(t){return W(d(t),23,4)},Z=function(t){return W(t,52,8)},Q=function(t,e,r){c(t[_],e,{configurable:!0,get:function(){return r(this)[e]}})},tt=function(t,e,r,n){var i=j(t),o=v(r),a=!!n;if(o+e>i.byteLength)throw new G(P);var s=i.bytes,u=o+i.byteOffset,c=w(s,u,u+e);return a?c:H(c)},et=function(t,e,r,n,i,o){var a=j(t),s=v(r),u=n(+i),c=!!o;if(s+e>a.byteLength)throw new G(P);for(var f=a.bytes,l=s+a.byteOffset,h=0;h>24)},setUint8:function(t,e){it(this,t,e<<24>>24)}},{unsafe:!0})}else C=(D=function(t){h(this,C);var e=v(t);R(this,{type:k,bytes:U(B(e),0),byteLength:e}),o||(this.byteLength=e,this.detached=!1)})[_],z=(F=function(t,e,r){h(this,z),h(t,C);var n=N(t),i=n.byteLength,a=p(e);if(a<0||a>i)throw new G("Wrong offset");if(a+(r=void 0===r?i-a:y(r))>i)throw new G("Wrong length");R(this,{type:M,buffer:t,byteLength:r,byteOffset:a,bytes:n.bytes}),o||(this.buffer=t,this.byteLength=r,this.byteOffset=a)})[_],o&&(Q(D,"byteLength",N),Q(F,"buffer",j),Q(F,"byteLength",j),Q(F,"byteOffset",j)),f(z,{getInt8:function(t){return tt(this,1,t)[0]<<24>>24},getUint8:function(t){return tt(this,1,t)[0]},getInt16:function(t){var e=tt(this,2,t,arguments.length>1&&arguments[1]);return(e[1]<<8|e[0])<<16>>16},getUint16:function(t){var e=tt(this,2,t,arguments.length>1&&arguments[1]);return e[1]<<8|e[0]},getInt32:function(t){return X(tt(this,4,t,arguments.length>1&&arguments[1]))},getUint32:function(t){return X(tt(this,4,t,arguments.length>1&&arguments[1]))>>>0},getFloat32:function(t){return Y(tt(this,4,t,arguments.length>1&&arguments[1]),23)},getFloat64:function(t){return Y(tt(this,8,t,arguments.length>1&&arguments[1]),52)},setInt8:function(t,e){et(this,1,t,$,e)},setUint8:function(t,e){et(this,1,t,$,e)},setInt16:function(t,e){et(this,2,t,q,e,arguments.length>2&&arguments[2])},setUint16:function(t,e){et(this,2,t,q,e,arguments.length>2&&arguments[2])},setInt32:function(t,e){et(this,4,t,K,e,arguments.length>2&&arguments[2])},setUint32:function(t,e){et(this,4,t,K,e,arguments.length>2&&arguments[2])},setFloat32:function(t,e){et(this,4,t,J,e,arguments.length>2&&arguments[2])},setFloat64:function(t,e){et(this,8,t,Z,e,arguments.length>2&&arguments[2])}});A(D,k),A(F,M),t.exports={ArrayBuffer:D,DataView:F}},7029:(t,e,r)=>{var n=r(8981),i=r(5610),o=r(6198),a=r(4606),s=Math.min;t.exports=[].copyWithin||function(t,e){var r=n(this),u=o(r),c=i(t,u),f=i(e,u),l=arguments.length>2?arguments[2]:void 0,h=s((void 0===l?u:i(l,u))-f,u-c),p=1;for(f0;)f in r?r[c]=r[f]:a(r,c),c+=p,f+=p;return r}},4373:(t,e,r)=>{var n=r(8981),i=r(5610),o=r(6198);t.exports=function(t){for(var e=n(this),r=o(e),a=arguments.length,s=i(a>1?arguments[1]:void 0,r),u=a>2?arguments[2]:void 0,c=void 0===u?r:i(u,r);c>s;)e[s++]=t;return e}},235:(t,e,r)=>{var n=r(9213).forEach,i=r(4598)("forEach");t.exports=i?[].forEach:function(t){return n(this,t,arguments.length>1?arguments[1]:void 0)}},5370:(t,e,r)=>{var n=r(6198);t.exports=function(t,e,r){for(var i=0,o=arguments.length>2?r:n(e),a=new t(o);o>i;)a[i]=e[i++];return a}},7916:(t,e,r)=>{var n=r(6080),i=r(9565),o=r(8981),a=r(6319),s=r(4209),u=r(3517),c=r(6198),f=r(4659),l=r(81),h=r(851),p=Array;t.exports=function(t){var e=o(t),r=u(this),y=arguments.length,v=y>1?arguments[1]:void 0,d=void 0!==v;d&&(v=n(v,y>2?arguments[2]:void 0));var g,m,x,b,w,S,E=h(e),A=0;if(!E||this===p&&s(E))for(g=c(e),m=r?new this(g):p(g);g>A;A++)S=d?v(e[A],A):e[A],f(m,A,S);else for(m=r?new this:[],w=(b=l(e,E)).next;!(x=i(w,b)).done;A++)S=d?a(b,v,[x.value,A],!0):x.value,f(m,A,S);return m.length=A,m}},9617:(t,e,r)=>{var n=r(5397),i=r(5610),o=r(6198),a=function(t){return function(e,r,a){var s=n(e),u=o(s);if(0===u)return!t&&-1;var c,f=i(a,u);if(t&&r!=r){for(;u>f;)if((c=s[f++])!=c)return!0}else for(;u>f;f++)if((t||f in s)&&s[f]===r)return t||f||0;return!t&&-1}};t.exports={includes:a(!0),indexOf:a(!1)}},9213:(t,e,r)=>{var n=r(6080),i=r(9504),o=r(7055),a=r(8981),s=r(6198),u=r(1469),c=i([].push),f=function(t){var e=1===t,r=2===t,i=3===t,f=4===t,l=6===t,h=7===t,p=5===t||l;return function(y,v,d,g){for(var m,x,b=a(y),w=o(b),S=s(w),E=n(v,d),A=0,O=g||u,I=e?O(y,S):r||h?O(y,0):void 0;S>A;A++)if((p||A in w)&&(x=E(m=w[A],A,b),t))if(e)I[A]=x;else if(x)switch(t){case 3:return!0;case 5:return m;case 6:return A;case 2:c(I,m)}else switch(t){case 4:return!1;case 7:c(I,m)}return l?-1:i||f?f:I}};t.exports={forEach:f(0),map:f(1),filter:f(2),some:f(3),every:f(4),find:f(5),findIndex:f(6),filterReject:f(7)}},8379:(t,e,r)=>{var n=r(8745),i=r(5397),o=r(1291),a=r(6198),s=r(4598),u=Math.min,c=[].lastIndexOf,f=!!c&&1/[1].lastIndexOf(1,-0)<0,l=s("lastIndexOf"),h=f||!l;t.exports=h?function(t){if(f)return n(c,this,arguments)||0;var e=i(this),r=a(e);if(0===r)return-1;var s=r-1;for(arguments.length>1&&(s=u(s,o(arguments[1]))),s<0&&(s=r+s);s>=0;s--)if(s in e&&e[s]===t)return s||0;return-1}:c},597:(t,e,r)=>{var n=r(9039),i=r(8227),o=r(7388),a=i("species");t.exports=function(t){return o>=51||!n((function(){var e=[];return(e.constructor={})[a]=function(){return{foo:1}},1!==e[t](Boolean).foo}))}},4598:(t,e,r)=>{var n=r(9039);t.exports=function(t,e){var r=[][t];return!!r&&n((function(){r.call(null,e||function(){return 1},1)}))}},926:(t,e,r)=>{var n=r(9306),i=r(8981),o=r(7055),a=r(6198),s=TypeError,u="Reduce of empty array with no initial value",c=function(t){return function(e,r,c,f){var l=i(e),h=o(l),p=a(l);if(n(r),0===p&&c<2)throw new s(u);var y=t?p-1:0,v=t?-1:1;if(c<2)for(;;){if(y in h){f=h[y],y+=v;break}if(y+=v,t?y<0:p<=y)throw new s(u)}for(;t?y>=0:p>y;y+=v)y in h&&(f=r(f,h[y],y,l));return f}};t.exports={left:c(!1),right:c(!0)}},4527:(t,e,r)=>{var n=r(3724),i=r(4376),o=TypeError,a=Object.getOwnPropertyDescriptor,s=n&&!function(){if(void 0!==this)return!0;try{Object.defineProperty([],"length",{writable:!1}).length=1}catch(t){return t instanceof TypeError}}();t.exports=s?function(t,e){if(i(t)&&!a(t,"length").writable)throw new o("Cannot set read only .length");return t.length=e}:function(t,e){return t.length=e}},7680:(t,e,r)=>{var n=r(9504);t.exports=n([].slice)},4488:(t,e,r)=>{var n=r(7680),i=Math.floor,o=function(t,e){var r=t.length;if(r<8)for(var a,s,u=1;u0;)t[s]=t[--s];s!==u++&&(t[s]=a)}else for(var c=i(r/2),f=o(n(t,0,c),e),l=o(n(t,c),e),h=f.length,p=l.length,y=0,v=0;y{var n=r(4376),i=r(3517),o=r(34),a=r(8227)("species"),s=Array;t.exports=function(t){var e;return n(t)&&(e=t.constructor,(i(e)&&(e===s||n(e.prototype))||o(e)&&null===(e=e[a]))&&(e=void 0)),void 0===e?s:e}},1469:(t,e,r)=>{var n=r(7433);t.exports=function(t,e){return new(n(t))(0===e?0:e)}},6319:(t,e,r)=>{var n=r(8551),i=r(9539);t.exports=function(t,e,r,o){try{return o?e(n(r)[0],r[1]):e(r)}catch(e){i(t,"throw",e)}}},4428:(t,e,r)=>{var n=r(8227)("iterator"),i=!1;try{var o=0,a={next:function(){return{done:!!o++}},return:function(){i=!0}};a[n]=function(){return this},Array.from(a,(function(){throw 2}))}catch(t){}t.exports=function(t,e){try{if(!e&&!i)return!1}catch(t){return!1}var r=!1;try{var o={};o[n]=function(){return{next:function(){return{done:r=!0}}}},t(o)}catch(t){}return r}},4576:(t,e,r)=>{var n=r(9504),i=n({}.toString),o=n("".slice);t.exports=function(t){return o(i(t),8,-1)}},6955:(t,e,r)=>{var n=r(2140),i=r(4901),o=r(4576),a=r(8227)("toStringTag"),s=Object,u="Arguments"===o(function(){return arguments}());t.exports=n?o:function(t){var e,r,n;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(r=function(t,e){try{return t[e]}catch(t){}}(e=s(t),a))?r:u?o(e):"Object"===(n=o(e))&&i(e.callee)?"Arguments":n}},6938:(t,e,r)=>{var n=r(2360),i=r(2106),o=r(6279),a=r(6080),s=r(679),u=r(4117),c=r(2652),f=r(1088),l=r(2529),h=r(7633),p=r(3724),y=r(3451).fastKey,v=r(1181),d=v.set,g=v.getterFor;t.exports={getConstructor:function(t,e,r,f){var l=t((function(t,i){s(t,h),d(t,{type:e,index:n(null),first:void 0,last:void 0,size:0}),p||(t.size=0),u(i)||c(i,t[f],{that:t,AS_ENTRIES:r})})),h=l.prototype,v=g(e),m=function(t,e,r){var n,i,o=v(t),a=x(t,e);return a?a.value=r:(o.last=a={index:i=y(e,!0),key:e,value:r,previous:n=o.last,next:void 0,removed:!1},o.first||(o.first=a),n&&(n.next=a),p?o.size++:t.size++,"F"!==i&&(o.index[i]=a)),t},x=function(t,e){var r,n=v(t),i=y(e);if("F"!==i)return n.index[i];for(r=n.first;r;r=r.next)if(r.key===e)return r};return o(h,{clear:function(){for(var t=v(this),e=t.first;e;)e.removed=!0,e.previous&&(e.previous=e.previous.next=void 0),e=e.next;t.first=t.last=void 0,t.index=n(null),p?t.size=0:this.size=0},delete:function(t){var e=this,r=v(e),n=x(e,t);if(n){var i=n.next,o=n.previous;delete r.index[n.index],n.removed=!0,o&&(o.next=i),i&&(i.previous=o),r.first===n&&(r.first=i),r.last===n&&(r.last=o),p?r.size--:e.size--}return!!n},forEach:function(t){for(var e,r=v(this),n=a(t,arguments.length>1?arguments[1]:void 0);e=e?e.next:r.first;)for(n(e.value,e.key,this);e&&e.removed;)e=e.previous},has:function(t){return!!x(this,t)}}),o(h,r?{get:function(t){var e=x(this,t);return e&&e.value},set:function(t,e){return m(this,0===t?0:t,e)}}:{add:function(t){return m(this,t=0===t?0:t,t)}}),p&&i(h,"size",{configurable:!0,get:function(){return v(this).size}}),l},setStrong:function(t,e,r){var n=e+" Iterator",i=g(e),o=g(n);f(t,e,(function(t,e){d(this,{type:n,target:t,state:i(t),kind:e,last:void 0})}),(function(){for(var t=o(this),e=t.kind,r=t.last;r&&r.removed;)r=r.previous;return t.target&&(t.last=r=r?r.next:t.state.first)?l("keys"===e?r.key:"values"===e?r.value:[r.key,r.value],!1):(t.target=void 0,l(void 0,!0))}),r?"entries":"values",!r,!0),h(e)}}},6468:(t,e,r)=>{var n=r(6518),i=r(4475),o=r(9504),a=r(2796),s=r(6840),u=r(3451),c=r(2652),f=r(679),l=r(4901),h=r(4117),p=r(34),y=r(9039),v=r(4428),d=r(687),g=r(3167);t.exports=function(t,e,r){var m=-1!==t.indexOf("Map"),x=-1!==t.indexOf("Weak"),b=m?"set":"add",w=i[t],S=w&&w.prototype,E=w,A={},O=function(t){var e=o(S[t]);s(S,t,"add"===t?function(t){return e(this,0===t?0:t),this}:"delete"===t?function(t){return!(x&&!p(t))&&e(this,0===t?0:t)}:"get"===t?function(t){return x&&!p(t)?void 0:e(this,0===t?0:t)}:"has"===t?function(t){return!(x&&!p(t))&&e(this,0===t?0:t)}:function(t,r){return e(this,0===t?0:t,r),this})};if(a(t,!l(w)||!(x||S.forEach&&!y((function(){(new w).entries().next()})))))E=r.getConstructor(e,t,m,b),u.enable();else if(a(t,!0)){var I=new E,T=I[b](x?{}:-0,1)!==I,k=y((function(){I.has(1)})),M=v((function(t){new w(t)})),_=!x&&y((function(){for(var t=new w,e=5;e--;)t[b](e,e);return!t.has(-0)}));M||((E=e((function(t,e){f(t,S);var r=g(new w,t,E);return h(e)||c(e,r[b],{that:r,AS_ENTRIES:m}),r}))).prototype=S,S.constructor=E),(k||_)&&(O("delete"),O("has"),m&&O("get")),(_||T)&&O(b),x&&S.clear&&delete S.clear}return A[t]=E,n({global:!0,constructor:!0,forced:E!==w},A),d(E,t),x||r.setStrong(E,t,m),E}},7740:(t,e,r)=>{var n=r(9297),i=r(5031),o=r(7347),a=r(4913);t.exports=function(t,e,r){for(var s=i(e),u=a.f,c=o.f,f=0;f{var n=r(8227)("match");t.exports=function(t){var e=/./;try{"/./"[t](e)}catch(r){try{return e[n]=!1,"/./"[t](e)}catch(t){}}return!1}},2211:(t,e,r)=>{var n=r(9039);t.exports=!n((function(){function t(){}return t.prototype.constructor=null,Object.getPrototypeOf(new t)!==t.prototype}))},7240:(t,e,r)=>{var n=r(9504),i=r(7750),o=r(655),a=/"/g,s=n("".replace);t.exports=function(t,e,r,n){var u=o(i(t)),c="<"+e;return""!==r&&(c+=" "+r+'="'+s(o(n),a,""")+'"'),c+">"+u+""}},2529:t=>{t.exports=function(t,e){return{value:t,done:e}}},6699:(t,e,r)=>{var n=r(3724),i=r(4913),o=r(6980);t.exports=n?function(t,e,r){return i.f(t,e,o(1,r))}:function(t,e,r){return t[e]=r,t}},6980:t=>{t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},4659:(t,e,r)=>{var n=r(3724),i=r(4913),o=r(6980);t.exports=function(t,e,r){n?i.f(t,e,o(0,r)):t[e]=r}},3640:(t,e,r)=>{var n=r(8551),i=r(4270),o=TypeError;t.exports=function(t){if(n(this),"string"===t||"default"===t)t="string";else if("number"!==t)throw new o("Incorrect hint");return i(this,t)}},2106:(t,e,r)=>{var n=r(283),i=r(4913);t.exports=function(t,e,r){return r.get&&n(r.get,e,{getter:!0}),r.set&&n(r.set,e,{setter:!0}),i.f(t,e,r)}},6840:(t,e,r)=>{var n=r(4901),i=r(4913),o=r(283),a=r(9433);t.exports=function(t,e,r,s){s||(s={});var u=s.enumerable,c=void 0!==s.name?s.name:e;if(n(r)&&o(r,c,s),s.global)u?t[e]=r:a(e,r);else{try{s.unsafe?t[e]&&(u=!0):delete t[e]}catch(t){}u?t[e]=r:i.f(t,e,{value:r,enumerable:!1,configurable:!s.nonConfigurable,writable:!s.nonWritable})}return t}},6279:(t,e,r)=>{var n=r(6840);t.exports=function(t,e,r){for(var i in e)n(t,i,e[i],r);return t}},9433:(t,e,r)=>{var n=r(4475),i=Object.defineProperty;t.exports=function(t,e){try{i(n,t,{value:e,configurable:!0,writable:!0})}catch(r){n[t]=e}return e}},4606:(t,e,r)=>{var n=r(6823),i=TypeError;t.exports=function(t,e){if(!delete t[e])throw new i("Cannot delete property "+n(e)+" of "+n(t))}},3724:(t,e,r)=>{var n=r(9039);t.exports=!n((function(){return 7!==Object.defineProperty({},1,{get:function(){return 7}})[1]}))},4055:(t,e,r)=>{var n=r(4475),i=r(34),o=n.document,a=i(o)&&i(o.createElement);t.exports=function(t){return a?o.createElement(t):{}}},6837:t=>{var e=TypeError;t.exports=function(t){if(t>9007199254740991)throw e("Maximum allowed index exceeded");return t}},7400:t=>{t.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}},9296:(t,e,r)=>{var n=r(4055)("span").classList,i=n&&n.constructor&&n.constructor.prototype;t.exports=i===Object.prototype?void 0:i},8834:(t,e,r)=>{var n=r(9392).match(/firefox\/(\d+)/i);t.exports=!!n&&+n[1]},3202:(t,e,r)=>{var n=r(9392);t.exports=/MSIE|Trident/.test(n)},9392:t=>{t.exports="undefined"!=typeof navigator&&String(navigator.userAgent)||""},7388:(t,e,r)=>{var n,i,o=r(4475),a=r(9392),s=o.process,u=o.Deno,c=s&&s.versions||u&&u.version,f=c&&c.v8;f&&(i=(n=f.split("."))[0]>0&&n[0]<4?1:+(n[0]+n[1])),!i&&a&&(!(n=a.match(/Edge\/(\d+)/))||n[1]>=74)&&(n=a.match(/Chrome\/(\d+)/))&&(i=+n[1]),t.exports=i},9160:(t,e,r)=>{var n=r(9392).match(/AppleWebKit\/(\d+)\./);t.exports=!!n&&+n[1]},8727:t=>{t.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},6518:(t,e,r)=>{var n=r(4475),i=r(7347).f,o=r(6699),a=r(6840),s=r(9433),u=r(7740),c=r(2796);t.exports=function(t,e){var r,f,l,h,p,y=t.target,v=t.global,d=t.stat;if(r=v?n:d?n[y]||s(y,{}):n[y]&&n[y].prototype)for(f in e){if(h=e[f],l=t.dontCallGetSet?(p=i(r,f))&&p.value:r[f],!c(v?f:y+(d?".":"#")+f,t.forced)&&void 0!==l){if(typeof h==typeof l)continue;u(h,l)}(t.sham||l&&l.sham)&&o(h,"sham",!0),a(r,f,h,t)}}},9039:t=>{t.exports=function(t){try{return!!t()}catch(t){return!0}}},9228:(t,e,r)=>{r(7495);var n=r(9565),i=r(6840),o=r(7323),a=r(9039),s=r(8227),u=r(6699),c=s("species"),f=RegExp.prototype;t.exports=function(t,e,r,l){var h=s(t),p=!a((function(){var e={};return e[h]=function(){return 7},7!==""[t](e)})),y=p&&!a((function(){var e=!1,r=/a/;return"split"===t&&((r={}).constructor={},r.constructor[c]=function(){return r},r.flags="",r[h]=/./[h]),r.exec=function(){return e=!0,null},r[h](""),!e}));if(!p||!y||r){var v=/./[h],d=e(h,""[t],(function(t,e,r,i,a){var s=e.exec;return s===o||s===f.exec?p&&!a?{done:!0,value:n(v,e,r,i)}:{done:!0,value:n(t,r,e,i)}:{done:!1}}));i(String.prototype,t,d[0]),i(f,h,d[1])}l&&u(f[h],"sham",!0)}},259:(t,e,r)=>{var n=r(4376),i=r(6198),o=r(6837),a=r(6080),s=function(t,e,r,u,c,f,l,h){for(var p,y,v=c,d=0,g=!!l&&a(l,h);d0&&n(p)?(y=i(p),v=s(t,e,p,y,v,f-1)-1):(o(v+1),t[v]=p),v++),d++;return v};t.exports=s},2744:(t,e,r)=>{var n=r(9039);t.exports=!n((function(){return Object.isExtensible(Object.preventExtensions({}))}))},8745:(t,e,r)=>{var n=r(616),i=Function.prototype,o=i.apply,a=i.call;t.exports="object"==typeof Reflect&&Reflect.apply||(n?a.bind(o):function(){return a.apply(o,arguments)})},6080:(t,e,r)=>{var n=r(7476),i=r(9306),o=r(616),a=n(n.bind);t.exports=function(t,e){return i(t),void 0===e?t:o?a(t,e):function(){return t.apply(e,arguments)}}},616:(t,e,r)=>{var n=r(9039);t.exports=!n((function(){var t=function(){}.bind();return"function"!=typeof t||t.hasOwnProperty("prototype")}))},9565:(t,e,r)=>{var n=r(616),i=Function.prototype.call;t.exports=n?i.bind(i):function(){return i.apply(i,arguments)}},350:(t,e,r)=>{var n=r(3724),i=r(9297),o=Function.prototype,a=n&&Object.getOwnPropertyDescriptor,s=i(o,"name"),u=s&&"something"===function(){}.name,c=s&&(!n||n&&a(o,"name").configurable);t.exports={EXISTS:s,PROPER:u,CONFIGURABLE:c}},6706:(t,e,r)=>{var n=r(9504),i=r(9306);t.exports=function(t,e,r){try{return n(i(Object.getOwnPropertyDescriptor(t,e)[r]))}catch(t){}}},7476:(t,e,r)=>{var n=r(4576),i=r(9504);t.exports=function(t){if("Function"===n(t))return i(t)}},9504:(t,e,r)=>{var n=r(616),i=Function.prototype,o=i.call,a=n&&i.bind.bind(o,o);t.exports=n?a:function(t){return function(){return o.apply(t,arguments)}}},7751:(t,e,r)=>{var n=r(4475),i=r(4901);t.exports=function(t,e){return arguments.length<2?(r=n[t],i(r)?r:void 0):n[t]&&n[t][e];var r}},851:(t,e,r)=>{var n=r(6955),i=r(5966),o=r(4117),a=r(6269),s=r(8227)("iterator");t.exports=function(t){if(!o(t))return i(t,s)||i(t,"@@iterator")||a[n(t)]}},81:(t,e,r)=>{var n=r(9565),i=r(9306),o=r(8551),a=r(6823),s=r(851),u=TypeError;t.exports=function(t,e){var r=arguments.length<2?s(t):e;if(i(r))return o(n(r,t));throw new u(a(t)+" is not iterable")}},6933:(t,e,r)=>{var n=r(9504),i=r(4376),o=r(4901),a=r(4576),s=r(655),u=n([].push);t.exports=function(t){if(o(t))return t;if(i(t)){for(var e=t.length,r=[],n=0;n{var n=r(9306),i=r(4117);t.exports=function(t,e){var r=t[e];return i(r)?void 0:n(r)}},2478:(t,e,r)=>{var n=r(9504),i=r(8981),o=Math.floor,a=n("".charAt),s=n("".replace),u=n("".slice),c=/\$([$&'`]|\d{1,2}|<[^>]*>)/g,f=/\$([$&'`]|\d{1,2})/g;t.exports=function(t,e,r,n,l,h){var p=r+t.length,y=n.length,v=f;return void 0!==l&&(l=i(l),v=c),s(h,v,(function(i,s){var c;switch(a(s,0)){case"$":return"$";case"&":return t;case"`":return u(e,0,r);case"'":return u(e,p);case"<":c=l[u(s,1,-1)];break;default:var f=+s;if(0===f)return i;if(f>y){var h=o(f/10);return 0===h?i:h<=y?void 0===n[h-1]?a(s,1):n[h-1]+a(s,1):i}c=n[f-1]}return void 0===c?"":c}))}},4475:function(t,e,r){var n=function(t){return t&&t.Math===Math&&t};t.exports=n("object"==typeof globalThis&&globalThis)||n("object"==typeof window&&window)||n("object"==typeof self&&self)||n("object"==typeof r.g&&r.g)||n("object"==typeof this&&this)||function(){return this}()||Function("return this")()},9297:(t,e,r)=>{var n=r(9504),i=r(8981),o=n({}.hasOwnProperty);t.exports=Object.hasOwn||function(t,e){return o(i(t),e)}},421:t=>{t.exports={}},397:(t,e,r)=>{var n=r(7751);t.exports=n("document","documentElement")},5917:(t,e,r)=>{var n=r(3724),i=r(9039),o=r(4055);t.exports=!n&&!i((function(){return 7!==Object.defineProperty(o("div"),"a",{get:function(){return 7}}).a}))},8490:t=>{var e=Array,r=Math.abs,n=Math.pow,i=Math.floor,o=Math.log,a=Math.LN2;t.exports={pack:function(t,s,u){var c,f,l,h=e(u),p=8*u-s-1,y=(1<>1,d=23===s?n(2,-24)-n(2,-77):0,g=t<0||0===t&&1/t<0?1:0,m=0;for((t=r(t))!=t||t===1/0?(f=t!=t?1:0,c=y):(c=i(o(t)/a),t*(l=n(2,-c))<1&&(c--,l*=2),(t+=c+v>=1?d/l:d*n(2,1-v))*l>=2&&(c++,l/=2),c+v>=y?(f=0,c=y):c+v>=1?(f=(t*l-1)*n(2,s),c+=v):(f=t*n(2,v-1)*n(2,s),c=0));s>=8;)h[m++]=255&f,f/=256,s-=8;for(c=c<0;)h[m++]=255&c,c/=256,p-=8;return h[--m]|=128*g,h},unpack:function(t,e){var r,i=t.length,o=8*i-e-1,a=(1<>1,u=o-7,c=i-1,f=t[c--],l=127&f;for(f>>=7;u>0;)l=256*l+t[c--],u-=8;for(r=l&(1<<-u)-1,l>>=-u,u+=e;u>0;)r=256*r+t[c--],u-=8;if(0===l)l=1-s;else{if(l===a)return r?NaN:f?-1/0:1/0;r+=n(2,e),l-=s}return(f?-1:1)*r*n(2,l-e)}}},7055:(t,e,r)=>{var n=r(9504),i=r(9039),o=r(4576),a=Object,s=n("".split);t.exports=i((function(){return!a("z").propertyIsEnumerable(0)}))?function(t){return"String"===o(t)?s(t,""):a(t)}:a},3167:(t,e,r)=>{var n=r(4901),i=r(34),o=r(2967);t.exports=function(t,e,r){var a,s;return o&&n(a=e.constructor)&&a!==r&&i(s=a.prototype)&&s!==r.prototype&&o(t,s),t}},3706:(t,e,r)=>{var n=r(9504),i=r(4901),o=r(7629),a=n(Function.toString);i(o.inspectSource)||(o.inspectSource=function(t){return a(t)}),t.exports=o.inspectSource},3451:(t,e,r)=>{var n=r(6518),i=r(9504),o=r(421),a=r(34),s=r(9297),u=r(4913).f,c=r(8480),f=r(298),l=r(4124),h=r(3392),p=r(2744),y=!1,v=h("meta"),d=0,g=function(t){u(t,v,{value:{objectID:"O"+d++,weakData:{}}})},m=t.exports={enable:function(){m.enable=function(){},y=!0;var t=c.f,e=i([].splice),r={};r[v]=1,t(r).length&&(c.f=function(r){for(var n=t(r),i=0,o=n.length;i{var n,i,o,a=r(8622),s=r(4475),u=r(34),c=r(6699),f=r(9297),l=r(7629),h=r(6119),p=r(421),y="Object already initialized",v=s.TypeError,d=s.WeakMap;if(a||l.state){var g=l.state||(l.state=new d);g.get=g.get,g.has=g.has,g.set=g.set,n=function(t,e){if(g.has(t))throw new v(y);return e.facade=t,g.set(t,e),e},i=function(t){return g.get(t)||{}},o=function(t){return g.has(t)}}else{var m=h("state");p[m]=!0,n=function(t,e){if(f(t,m))throw new v(y);return e.facade=t,c(t,m,e),e},i=function(t){return f(t,m)?t[m]:{}},o=function(t){return f(t,m)}}t.exports={set:n,get:i,has:o,enforce:function(t){return o(t)?i(t):n(t,{})},getterFor:function(t){return function(e){var r;if(!u(e)||(r=i(e)).type!==t)throw new v("Incompatible receiver, "+t+" required");return r}}}},4209:(t,e,r)=>{var n=r(8227),i=r(6269),o=n("iterator"),a=Array.prototype;t.exports=function(t){return void 0!==t&&(i.Array===t||a[o]===t)}},4376:(t,e,r)=>{var n=r(4576);t.exports=Array.isArray||function(t){return"Array"===n(t)}},1108:(t,e,r)=>{var n=r(6955);t.exports=function(t){var e=n(t);return"BigInt64Array"===e||"BigUint64Array"===e}},4901:t=>{var e="object"==typeof document&&document.all;t.exports=void 0===e&&void 0!==e?function(t){return"function"==typeof t||t===e}:function(t){return"function"==typeof t}},3517:(t,e,r)=>{var n=r(9504),i=r(9039),o=r(4901),a=r(6955),s=r(7751),u=r(3706),c=function(){},f=s("Reflect","construct"),l=/^\s*(?:class|function)\b/,h=n(l.exec),p=!l.test(c),y=function(t){if(!o(t))return!1;try{return f(c,[],t),!0}catch(t){return!1}},v=function(t){if(!o(t))return!1;switch(a(t)){case"AsyncFunction":case"GeneratorFunction":case"AsyncGeneratorFunction":return!1}try{return p||!!h(l,u(t))}catch(t){return!0}};v.sham=!0,t.exports=!f||i((function(){var t;return y(y.call)||!y(Object)||!y((function(){t=!0}))||t}))?v:y},2796:(t,e,r)=>{var n=r(9039),i=r(4901),o=/#|\.prototype\./,a=function(t,e){var r=u[s(t)];return r===f||r!==c&&(i(e)?n(e):!!e)},s=a.normalize=function(t){return String(t).replace(o,".").toLowerCase()},u=a.data={},c=a.NATIVE="N",f=a.POLYFILL="P";t.exports=a},2087:(t,e,r)=>{var n=r(34),i=Math.floor;t.exports=Number.isInteger||function(t){return!n(t)&&isFinite(t)&&i(t)===t}},4117:t=>{t.exports=function(t){return null==t}},34:(t,e,r)=>{var n=r(4901);t.exports=function(t){return"object"==typeof t?null!==t:n(t)}},3925:(t,e,r)=>{var n=r(34);t.exports=function(t){return n(t)||null===t}},6395:t=>{t.exports=!1},788:(t,e,r)=>{var n=r(34),i=r(4576),o=r(8227)("match");t.exports=function(t){var e;return n(t)&&(void 0!==(e=t[o])?!!e:"RegExp"===i(t))}},757:(t,e,r)=>{var n=r(7751),i=r(4901),o=r(1625),a=r(7040),s=Object;t.exports=a?function(t){return"symbol"==typeof t}:function(t){var e=n("Symbol");return i(e)&&o(e.prototype,s(t))}},2652:(t,e,r)=>{var n=r(6080),i=r(9565),o=r(8551),a=r(6823),s=r(4209),u=r(6198),c=r(1625),f=r(81),l=r(851),h=r(9539),p=TypeError,y=function(t,e){this.stopped=t,this.result=e},v=y.prototype;t.exports=function(t,e,r){var d,g,m,x,b,w,S,E=r&&r.that,A=!(!r||!r.AS_ENTRIES),O=!(!r||!r.IS_RECORD),I=!(!r||!r.IS_ITERATOR),T=!(!r||!r.INTERRUPTED),k=n(e,E),M=function(t){return d&&h(d,"normal",t),new y(!0,t)},_=function(t){return A?(o(t),T?k(t[0],t[1],M):k(t[0],t[1])):T?k(t,M):k(t)};if(O)d=t.iterator;else if(I)d=t;else{if(!(g=l(t)))throw new p(a(t)+" is not iterable");if(s(g)){for(m=0,x=u(t);x>m;m++)if((b=_(t[m]))&&c(v,b))return b;return new y(!1)}d=f(t,g)}for(w=O?t.next:d.next;!(S=i(w,d)).done;){try{b=_(S.value)}catch(t){h(d,"throw",t)}if("object"==typeof b&&b&&c(v,b))return b}return new y(!1)}},9539:(t,e,r)=>{var n=r(9565),i=r(8551),o=r(5966);t.exports=function(t,e,r){var a,s;i(t);try{if(!(a=o(t,"return"))){if("throw"===e)throw r;return r}a=n(a,t)}catch(t){s=!0,a=t}if("throw"===e)throw r;if(s)throw a;return i(a),r}},3994:(t,e,r)=>{var n=r(7657).IteratorPrototype,i=r(2360),o=r(6980),a=r(687),s=r(6269),u=function(){return this};t.exports=function(t,e,r,c){var f=e+" Iterator";return t.prototype=i(n,{next:o(+!c,r)}),a(t,f,!1,!0),s[f]=u,t}},1088:(t,e,r)=>{var n=r(6518),i=r(9565),o=r(6395),a=r(350),s=r(4901),u=r(3994),c=r(2787),f=r(2967),l=r(687),h=r(6699),p=r(6840),y=r(8227),v=r(6269),d=r(7657),g=a.PROPER,m=a.CONFIGURABLE,x=d.IteratorPrototype,b=d.BUGGY_SAFARI_ITERATORS,w=y("iterator"),S="keys",E="values",A="entries",O=function(){return this};t.exports=function(t,e,r,a,y,d,I){u(r,e,a);var T,k,M,_=function(t){if(t===y&&V)return V;if(!b&&t&&t in j)return j[t];switch(t){case S:case E:case A:return function(){return new r(this,t)}}return function(){return new r(this)}},P=e+" Iterator",N=!1,j=t.prototype,R=j[w]||j["@@iterator"]||y&&j[y],V=!b&&R||_(y),D="Array"===e&&j.entries||R;if(D&&(T=c(D.call(new t)))!==Object.prototype&&T.next&&(o||c(T)===x||(f?f(T,x):s(T[w])||p(T,w,O)),l(T,P,!0,!0),o&&(v[P]=O)),g&&y===E&&R&&R.name!==E&&(!o&&m?h(j,"name",E):(N=!0,V=function(){return i(R,this)})),y)if(k={values:_(E),keys:d?V:_(S),entries:_(A)},I)for(M in k)(b||N||!(M in j))&&p(j,M,k[M]);else n({target:e,proto:!0,forced:b||N},k);return o&&!I||j[w]===V||p(j,w,V,{name:y}),v[e]=V,k}},7657:(t,e,r)=>{var n,i,o,a=r(9039),s=r(4901),u=r(34),c=r(2360),f=r(2787),l=r(6840),h=r(8227),p=r(6395),y=h("iterator"),v=!1;[].keys&&("next"in(o=[].keys())?(i=f(f(o)))!==Object.prototype&&(n=i):v=!0),!u(n)||a((function(){var t={};return n[y].call(t)!==t}))?n={}:p&&(n=c(n)),s(n[y])||l(n,y,(function(){return this})),t.exports={IteratorPrototype:n,BUGGY_SAFARI_ITERATORS:v}},6269:t=>{t.exports={}},6198:(t,e,r)=>{var n=r(8014);t.exports=function(t){return n(t.length)}},283:(t,e,r)=>{var n=r(9504),i=r(9039),o=r(4901),a=r(9297),s=r(3724),u=r(350).CONFIGURABLE,c=r(3706),f=r(1181),l=f.enforce,h=f.get,p=String,y=Object.defineProperty,v=n("".slice),d=n("".replace),g=n([].join),m=s&&!i((function(){return 8!==y((function(){}),"length",{value:8}).length})),x=String(String).split("String"),b=t.exports=function(t,e,r){"Symbol("===v(p(e),0,7)&&(e="["+d(p(e),/^Symbol\(([^)]*)\).*$/,"$1")+"]"),r&&r.getter&&(e="get "+e),r&&r.setter&&(e="set "+e),(!a(t,"name")||u&&t.name!==e)&&(s?y(t,"name",{value:e,configurable:!0}):t.name=e),m&&r&&a(r,"arity")&&t.length!==r.arity&&y(t,"length",{value:r.arity});try{r&&a(r,"constructor")&&r.constructor?s&&y(t,"prototype",{writable:!1}):t.prototype&&(t.prototype=void 0)}catch(t){}var n=l(t);return a(n,"source")||(n.source=g(x,"string"==typeof e?e:"")),t};Function.prototype.toString=b((function(){return o(this)&&h(this).source||c(this)}),"toString")},3164:(t,e,r)=>{var n=r(7782),i=Math.abs,o=2220446049250313e-31,a=1/o;t.exports=function(t,e,r,s){var u=+t,c=i(u),f=n(u);if(cr||h!=h?f*(1/0):f*h}},5617:(t,e,r)=>{var n=r(3164);t.exports=Math.fround||function(t){return n(t,1.1920928955078125e-7,34028234663852886e22,11754943508222875e-54)}},7782:t=>{t.exports=Math.sign||function(t){var e=+t;return 0===e||e!=e?e:e<0?-1:1}},741:t=>{var e=Math.ceil,r=Math.floor;t.exports=Math.trunc||function(t){var n=+t;return(n>0?r:e)(n)}},5749:(t,e,r)=>{var n=r(788),i=TypeError;t.exports=function(t){if(n(t))throw new i("The method doesn't accept regular expressions");return t}},3904:(t,e,r)=>{var n=r(4475),i=r(9039),o=r(9504),a=r(655),s=r(3802).trim,u=r(7452),c=o("".charAt),f=n.parseFloat,l=n.Symbol,h=l&&l.iterator,p=1/f(u+"-0")!=-1/0||h&&!i((function(){f(Object(h))}));t.exports=p?function(t){var e=s(a(t)),r=f(e);return 0===r&&"-"===c(e,0)?-0:r}:f},2360:(t,e,r)=>{var n,i=r(8551),o=r(6801),a=r(8727),s=r(421),u=r(397),c=r(4055),f=r(6119),l="prototype",h="script",p=f("IE_PROTO"),y=function(){},v=function(t){return"<"+h+">"+t+""},d=function(t){t.write(v("")),t.close();var e=t.parentWindow.Object;return t=null,e},g=function(){try{n=new ActiveXObject("htmlfile")}catch(t){}var t,e,r;g="undefined"!=typeof document?document.domain&&n?d(n):(e=c("iframe"),r="java"+h+":",e.style.display="none",u.appendChild(e),e.src=String(r),(t=e.contentWindow.document).open(),t.write(v("document.F=Object")),t.close(),t.F):d(n);for(var i=a.length;i--;)delete g[l][a[i]];return g()};s[p]=!0,t.exports=Object.create||function(t,e){var r;return null!==t?(y[l]=i(t),r=new y,y[l]=null,r[p]=t):r=g(),void 0===e?r:o.f(r,e)}},6801:(t,e,r)=>{var n=r(3724),i=r(8686),o=r(4913),a=r(8551),s=r(5397),u=r(1072);e.f=n&&!i?Object.defineProperties:function(t,e){a(t);for(var r,n=s(e),i=u(e),c=i.length,f=0;c>f;)o.f(t,r=i[f++],n[r]);return t}},4913:(t,e,r)=>{var n=r(3724),i=r(5917),o=r(8686),a=r(8551),s=r(6969),u=TypeError,c=Object.defineProperty,f=Object.getOwnPropertyDescriptor,l="enumerable",h="configurable",p="writable";e.f=n?o?function(t,e,r){if(a(t),e=s(e),a(r),"function"==typeof t&&"prototype"===e&&"value"in r&&p in r&&!r[p]){var n=f(t,e);n&&n[p]&&(t[e]=r.value,r={configurable:h in r?r[h]:n[h],enumerable:l in r?r[l]:n[l],writable:!1})}return c(t,e,r)}:c:function(t,e,r){if(a(t),e=s(e),a(r),i)try{return c(t,e,r)}catch(t){}if("get"in r||"set"in r)throw new u("Accessors not supported");return"value"in r&&(t[e]=r.value),t}},7347:(t,e,r)=>{var n=r(3724),i=r(9565),o=r(8773),a=r(6980),s=r(5397),u=r(6969),c=r(9297),f=r(5917),l=Object.getOwnPropertyDescriptor;e.f=n?l:function(t,e){if(t=s(t),e=u(e),f)try{return l(t,e)}catch(t){}if(c(t,e))return a(!i(o.f,t,e),t[e])}},298:(t,e,r)=>{var n=r(4576),i=r(5397),o=r(8480).f,a=r(7680),s="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];t.exports.f=function(t){return s&&"Window"===n(t)?function(t){try{return o(t)}catch(t){return a(s)}}(t):o(i(t))}},8480:(t,e,r)=>{var n=r(1828),i=r(8727).concat("length","prototype");e.f=Object.getOwnPropertyNames||function(t){return n(t,i)}},3717:(t,e)=>{e.f=Object.getOwnPropertySymbols},2787:(t,e,r)=>{var n=r(9297),i=r(4901),o=r(8981),a=r(6119),s=r(2211),u=a("IE_PROTO"),c=Object,f=c.prototype;t.exports=s?c.getPrototypeOf:function(t){var e=o(t);if(n(e,u))return e[u];var r=e.constructor;return i(r)&&e instanceof r?r.prototype:e instanceof c?f:null}},4124:(t,e,r)=>{var n=r(9039),i=r(34),o=r(4576),a=r(5652),s=Object.isExtensible,u=n((function(){s(1)}));t.exports=u||a?function(t){return!!i(t)&&(!a||"ArrayBuffer"!==o(t))&&(!s||s(t))}:s},1625:(t,e,r)=>{var n=r(9504);t.exports=n({}.isPrototypeOf)},1828:(t,e,r)=>{var n=r(9504),i=r(9297),o=r(5397),a=r(9617).indexOf,s=r(421),u=n([].push);t.exports=function(t,e){var r,n=o(t),c=0,f=[];for(r in n)!i(s,r)&&i(n,r)&&u(f,r);for(;e.length>c;)i(n,r=e[c++])&&(~a(f,r)||u(f,r));return f}},1072:(t,e,r)=>{var n=r(1828),i=r(8727);t.exports=Object.keys||function(t){return n(t,i)}},8773:(t,e)=>{var r={}.propertyIsEnumerable,n=Object.getOwnPropertyDescriptor,i=n&&!r.call({1:2},1);e.f=i?function(t){var e=n(this,t);return!!e&&e.enumerable}:r},2967:(t,e,r)=>{var n=r(6706),i=r(34),o=r(7750),a=r(3506);t.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var t,e=!1,r={};try{(t=n(Object.prototype,"__proto__","set"))(r,[]),e=r instanceof Array}catch(t){}return function(r,n){return o(r),a(n),i(r)?(e?t(r,n):r.__proto__=n,r):r}}():void 0)},3179:(t,e,r)=>{var n=r(2140),i=r(6955);t.exports=n?{}.toString:function(){return"[object "+i(this)+"]"}},4270:(t,e,r)=>{var n=r(9565),i=r(4901),o=r(34),a=TypeError;t.exports=function(t,e){var r,s;if("string"===e&&i(r=t.toString)&&!o(s=n(r,t)))return s;if(i(r=t.valueOf)&&!o(s=n(r,t)))return s;if("string"!==e&&i(r=t.toString)&&!o(s=n(r,t)))return s;throw new a("Can't convert object to primitive value")}},5031:(t,e,r)=>{var n=r(7751),i=r(9504),o=r(8480),a=r(3717),s=r(8551),u=i([].concat);t.exports=n("Reflect","ownKeys")||function(t){var e=o.f(s(t)),r=a.f;return r?u(e,r(t)):e}},9167:(t,e,r)=>{var n=r(4475);t.exports=n},1056:(t,e,r)=>{var n=r(4913).f;t.exports=function(t,e,r){r in t||n(t,r,{configurable:!0,get:function(){return e[r]},set:function(t){e[r]=t}})}},6682:(t,e,r)=>{var n=r(9565),i=r(8551),o=r(4901),a=r(4576),s=r(7323),u=TypeError;t.exports=function(t,e){var r=t.exec;if(o(r)){var c=n(r,t,e);return null!==c&&i(c),c}if("RegExp"===a(t))return n(s,t,e);throw new u("RegExp#exec called on incompatible receiver")}},7323:(t,e,r)=>{var n,i,o=r(9565),a=r(9504),s=r(655),u=r(7979),c=r(8429),f=r(5745),l=r(2360),h=r(1181).get,p=r(3635),y=r(8814),v=f("native-string-replace",String.prototype.replace),d=RegExp.prototype.exec,g=d,m=a("".charAt),x=a("".indexOf),b=a("".replace),w=a("".slice),S=(i=/b*/g,o(d,n=/a/,"a"),o(d,i,"a"),0!==n.lastIndex||0!==i.lastIndex),E=c.BROKEN_CARET,A=void 0!==/()??/.exec("")[1];(S||A||E||p||y)&&(g=function(t){var e,r,n,i,a,c,f,p=this,y=h(p),O=s(t),I=y.raw;if(I)return I.lastIndex=p.lastIndex,e=o(g,I,O),p.lastIndex=I.lastIndex,e;var T=y.groups,k=E&&p.sticky,M=o(u,p),_=p.source,P=0,N=O;if(k&&(M=b(M,"y",""),-1===x(M,"g")&&(M+="g"),N=w(O,p.lastIndex),p.lastIndex>0&&(!p.multiline||p.multiline&&"\n"!==m(O,p.lastIndex-1))&&(_="(?: "+_+")",N=" "+N,P++),r=new RegExp("^(?:"+_+")",M)),A&&(r=new RegExp("^"+_+"$(?!\\s)",M)),S&&(n=p.lastIndex),i=o(d,k?r:p,N),k?i?(i.input=w(i.input,P),i[0]=w(i[0],P),i.index=p.lastIndex,p.lastIndex+=i[0].length):p.lastIndex=0:S&&i&&(p.lastIndex=p.global?i.index+i[0].length:n),A&&i&&i.length>1&&o(v,i[0],r,(function(){for(a=1;a{var n=r(8551);t.exports=function(){var t=n(this),e="";return t.hasIndices&&(e+="d"),t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.dotAll&&(e+="s"),t.unicode&&(e+="u"),t.unicodeSets&&(e+="v"),t.sticky&&(e+="y"),e}},1034:(t,e,r)=>{var n=r(9565),i=r(9297),o=r(1625),a=r(7979),s=RegExp.prototype;t.exports=function(t){var e=t.flags;return void 0!==e||"flags"in s||i(t,"flags")||!o(s,t)?e:n(a,t)}},8429:(t,e,r)=>{var n=r(9039),i=r(4475).RegExp,o=n((function(){var t=i("a","y");return t.lastIndex=2,null!==t.exec("abcd")})),a=o||n((function(){return!i("a","y").sticky})),s=o||n((function(){var t=i("^r","gy");return t.lastIndex=2,null!==t.exec("str")}));t.exports={BROKEN_CARET:s,MISSED_STICKY:a,UNSUPPORTED_Y:o}},3635:(t,e,r)=>{var n=r(9039),i=r(4475).RegExp;t.exports=n((function(){var t=i(".","s");return!(t.dotAll&&t.test("\n")&&"s"===t.flags)}))},8814:(t,e,r)=>{var n=r(9039),i=r(4475).RegExp;t.exports=n((function(){var t=i("(?b)","g");return"b"!==t.exec("b").groups.a||"bc"!=="b".replace(t,"$c")}))},7750:(t,e,r)=>{var n=r(4117),i=TypeError;t.exports=function(t){if(n(t))throw new i("Can't call method on "+t);return t}},7633:(t,e,r)=>{var n=r(7751),i=r(2106),o=r(8227),a=r(3724),s=o("species");t.exports=function(t){var e=n(t);a&&e&&!e[s]&&i(e,s,{configurable:!0,get:function(){return this}})}},687:(t,e,r)=>{var n=r(4913).f,i=r(9297),o=r(8227)("toStringTag");t.exports=function(t,e,r){t&&!r&&(t=t.prototype),t&&!i(t,o)&&n(t,o,{configurable:!0,value:e})}},6119:(t,e,r)=>{var n=r(5745),i=r(3392),o=n("keys");t.exports=function(t){return o[t]||(o[t]=i(t))}},7629:(t,e,r)=>{var n=r(6395),i=r(4475),o=r(9433),a="__core-js_shared__",s=t.exports=i[a]||o(a,{});(s.versions||(s.versions=[])).push({version:"3.37.0",mode:n?"pure":"global",copyright:"© 2014-2024 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.37.0/LICENSE",source:"https://github.com/zloirock/core-js"})},5745:(t,e,r)=>{var n=r(7629);t.exports=function(t,e){return n[t]||(n[t]=e||{})}},2293:(t,e,r)=>{var n=r(8551),i=r(5548),o=r(4117),a=r(8227)("species");t.exports=function(t,e){var r,s=n(t).constructor;return void 0===s||o(r=n(s)[a])?e:i(r)}},3061:(t,e,r)=>{var n=r(9039);t.exports=function(t){return n((function(){var e=""[t]('"');return e!==e.toLowerCase()||e.split('"').length>3}))}},8183:(t,e,r)=>{var n=r(9504),i=r(1291),o=r(655),a=r(7750),s=n("".charAt),u=n("".charCodeAt),c=n("".slice),f=function(t){return function(e,r){var n,f,l=o(a(e)),h=i(r),p=l.length;return h<0||h>=p?t?"":void 0:(n=u(l,h))<55296||n>56319||h+1===p||(f=u(l,h+1))<56320||f>57343?t?s(l,h):n:t?c(l,h,h+2):f-56320+(n-55296<<10)+65536}};t.exports={codeAt:f(!1),charAt:f(!0)}},2333:(t,e,r)=>{var n=r(1291),i=r(655),o=r(7750),a=RangeError;t.exports=function(t){var e=i(o(this)),r="",s=n(t);if(s<0||s===1/0)throw new a("Wrong number of repetitions");for(;s>0;(s>>>=1)&&(e+=e))1&s&&(r+=e);return r}},3802:(t,e,r)=>{var n=r(9504),i=r(7750),o=r(655),a=r(7452),s=n("".replace),u=RegExp("^["+a+"]+"),c=RegExp("(^|[^"+a+"])["+a+"]+$"),f=function(t){return function(e){var r=o(i(e));return 1&t&&(r=s(r,u,"")),2&t&&(r=s(r,c,"$1")),r}};t.exports={start:f(1),end:f(2),trim:f(3)}},4495:(t,e,r)=>{var n=r(7388),i=r(9039),o=r(4475).String;t.exports=!!Object.getOwnPropertySymbols&&!i((function(){var t=Symbol("symbol detection");return!o(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&n&&n<41}))},8242:(t,e,r)=>{var n=r(9565),i=r(7751),o=r(8227),a=r(6840);t.exports=function(){var t=i("Symbol"),e=t&&t.prototype,r=e&&e.valueOf,s=o("toPrimitive");e&&!e[s]&&a(e,s,(function(t){return n(r,this)}),{arity:1})}},1296:(t,e,r)=>{var n=r(4495);t.exports=n&&!!Symbol.for&&!!Symbol.keyFor},1240:(t,e,r)=>{var n=r(9504);t.exports=n(1..valueOf)},5610:(t,e,r)=>{var n=r(1291),i=Math.max,o=Math.min;t.exports=function(t,e){var r=n(t);return r<0?i(r+e,0):o(r,e)}},5854:(t,e,r)=>{var n=r(2777),i=TypeError;t.exports=function(t){var e=n(t,"number");if("number"==typeof e)throw new i("Can't convert number to bigint");return BigInt(e)}},7696:(t,e,r)=>{var n=r(1291),i=r(8014),o=RangeError;t.exports=function(t){if(void 0===t)return 0;var e=n(t),r=i(e);if(e!==r)throw new o("Wrong length or index");return r}},5397:(t,e,r)=>{var n=r(7055),i=r(7750);t.exports=function(t){return n(i(t))}},1291:(t,e,r)=>{var n=r(741);t.exports=function(t){var e=+t;return e!=e||0===e?0:n(e)}},8014:(t,e,r)=>{var n=r(1291),i=Math.min;t.exports=function(t){var e=n(t);return e>0?i(e,9007199254740991):0}},8981:(t,e,r)=>{var n=r(7750),i=Object;t.exports=function(t){return i(n(t))}},8229:(t,e,r)=>{var n=r(9590),i=RangeError;t.exports=function(t,e){var r=n(t);if(r%e)throw new i("Wrong offset");return r}},9590:(t,e,r)=>{var n=r(1291),i=RangeError;t.exports=function(t){var e=n(t);if(e<0)throw new i("The argument can't be less than 0");return e}},2777:(t,e,r)=>{var n=r(9565),i=r(34),o=r(757),a=r(5966),s=r(4270),u=r(8227),c=TypeError,f=u("toPrimitive");t.exports=function(t,e){if(!i(t)||o(t))return t;var r,u=a(t,f);if(u){if(void 0===e&&(e="default"),r=n(u,t,e),!i(r)||o(r))return r;throw new c("Can't convert object to primitive value")}return void 0===e&&(e="number"),s(t,e)}},6969:(t,e,r)=>{var n=r(2777),i=r(757);t.exports=function(t){var e=n(t,"string");return i(e)?e:e+""}},2140:(t,e,r)=>{var n={};n[r(8227)("toStringTag")]="z",t.exports="[object z]"===String(n)},655:(t,e,r)=>{var n=r(6955),i=String;t.exports=function(t){if("Symbol"===n(t))throw new TypeError("Cannot convert a Symbol value to a string");return i(t)}},8319:t=>{var e=Math.round;t.exports=function(t){var r=e(t);return r<0?0:r>255?255:255&r}},6823:t=>{var e=String;t.exports=function(t){try{return e(t)}catch(t){return"Object"}}},5823:(t,e,r)=>{var n=r(6518),i=r(4475),o=r(9565),a=r(3724),s=r(2805),u=r(4644),c=r(6346),f=r(679),l=r(6980),h=r(6699),p=r(2087),y=r(8014),v=r(7696),d=r(8229),g=r(8319),m=r(6969),x=r(9297),b=r(6955),w=r(34),S=r(757),E=r(2360),A=r(1625),O=r(2967),I=r(8480).f,T=r(3251),k=r(9213).forEach,M=r(7633),_=r(2106),P=r(4913),N=r(7347),j=r(5370),R=r(1181),V=r(3167),D=R.get,C=R.set,F=R.enforce,z=P.f,L=N.f,B=i.RangeError,G=c.ArrayBuffer,U=G.prototype,H=c.DataView,W=u.NATIVE_ARRAY_BUFFER_VIEWS,Y=u.TYPED_ARRAY_TAG,$=u.TypedArray,q=u.TypedArrayPrototype,K=u.isTypedArray,X="BYTES_PER_ELEMENT",J="Wrong length",Z=function(t,e){_(t,e,{configurable:!0,get:function(){return D(this)[e]}})},Q=function(t){var e;return A(U,t)||"ArrayBuffer"===(e=b(t))||"SharedArrayBuffer"===e},tt=function(t,e){return K(t)&&!S(e)&&e in t&&p(+e)&&e>=0},et=function(t,e){return e=m(e),tt(t,e)?l(2,t[e]):L(t,e)},rt=function(t,e,r){return e=m(e),!(tt(t,e)&&w(r)&&x(r,"value"))||x(r,"get")||x(r,"set")||r.configurable||x(r,"writable")&&!r.writable||x(r,"enumerable")&&!r.enumerable?z(t,e,r):(t[e]=r.value,t)};a?(W||(N.f=et,P.f=rt,Z(q,"buffer"),Z(q,"byteOffset"),Z(q,"byteLength"),Z(q,"length")),n({target:"Object",stat:!0,forced:!W},{getOwnPropertyDescriptor:et,defineProperty:rt}),t.exports=function(t,e,r){var a=t.match(/\d+/)[0]/8,u=t+(r?"Clamped":"")+"Array",c="get"+t,l="set"+t,p=i[u],m=p,x=m&&m.prototype,b={},S=function(t,e){z(t,e,{get:function(){return function(t,e){var r=D(t);return r.view[c](e*a+r.byteOffset,!0)}(this,e)},set:function(t){return function(t,e,n){var i=D(t);i.view[l](e*a+i.byteOffset,r?g(n):n,!0)}(this,e,t)},enumerable:!0})};W?s&&(m=e((function(t,e,r,n){return f(t,x),V(w(e)?Q(e)?void 0!==n?new p(e,d(r,a),n):void 0!==r?new p(e,d(r,a)):new p(e):K(e)?j(m,e):o(T,m,e):new p(v(e)),t,m)})),O&&O(m,$),k(I(p),(function(t){t in m||h(m,t,p[t])})),m.prototype=x):(m=e((function(t,e,r,n){f(t,x);var i,s,u,c=0,l=0;if(w(e)){if(!Q(e))return K(e)?j(m,e):o(T,m,e);i=e,l=d(r,a);var h=e.byteLength;if(void 0===n){if(h%a)throw new B(J);if((s=h-l)<0)throw new B(J)}else if((s=y(n)*a)+l>h)throw new B(J);u=s/a}else u=v(e),i=new G(s=u*a);for(C(t,{buffer:i,byteOffset:l,byteLength:s,length:u,view:new H(i)});c{var n=r(4475),i=r(9039),o=r(4428),a=r(4644).NATIVE_ARRAY_BUFFER_VIEWS,s=n.ArrayBuffer,u=n.Int8Array;t.exports=!a||!i((function(){u(1)}))||!i((function(){new u(-1)}))||!o((function(t){new u,new u(null),new u(1.5),new u(t)}),!0)||i((function(){return 1!==new u(new s(2),1,void 0).length}))},6357:(t,e,r)=>{var n=r(5370),i=r(1412);t.exports=function(t,e){return n(i(t),e)}},3251:(t,e,r)=>{var n=r(6080),i=r(9565),o=r(5548),a=r(8981),s=r(6198),u=r(81),c=r(851),f=r(4209),l=r(1108),h=r(4644).aTypedArrayConstructor,p=r(5854);t.exports=function(t){var e,r,y,v,d,g,m,x,b=o(this),w=a(t),S=arguments.length,E=S>1?arguments[1]:void 0,A=void 0!==E,O=c(w);if(O&&!f(O))for(x=(m=u(w,O)).next,w=[];!(g=i(x,m)).done;)w.push(g.value);for(A&&S>2&&(E=n(E,arguments[2])),r=s(w),y=new(h(b))(r),v=l(y),e=0;r>e;e++)d=A?E(w[e],e):w[e],y[e]=v?p(d):+d;return y}},1412:(t,e,r)=>{var n=r(4644),i=r(2293),o=n.aTypedArrayConstructor,a=n.getTypedArrayConstructor;t.exports=function(t){return o(i(t,a(t)))}},3392:(t,e,r)=>{var n=r(9504),i=0,o=Math.random(),a=n(1..toString);t.exports=function(t){return"Symbol("+(void 0===t?"":t)+")_"+a(++i+o,36)}},7040:(t,e,r)=>{var n=r(4495);t.exports=n&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},8686:(t,e,r)=>{var n=r(3724),i=r(9039);t.exports=n&&i((function(){return 42!==Object.defineProperty((function(){}),"prototype",{value:42,writable:!1}).prototype}))},8622:(t,e,r)=>{var n=r(4475),i=r(4901),o=n.WeakMap;t.exports=i(o)&&/native code/.test(String(o))},511:(t,e,r)=>{var n=r(9167),i=r(9297),o=r(1951),a=r(4913).f;t.exports=function(t){var e=n.Symbol||(n.Symbol={});i(e,t)||a(e,t,{value:o.f(t)})}},1951:(t,e,r)=>{var n=r(8227);e.f=n},8227:(t,e,r)=>{var n=r(4475),i=r(5745),o=r(9297),a=r(3392),s=r(4495),u=r(7040),c=n.Symbol,f=i("wks"),l=u?c.for||c:c&&c.withoutSetter||a;t.exports=function(t){return o(f,t)||(f[t]=s&&o(c,t)?c[t]:l("Symbol."+t)),f[t]}},7452:t=>{t.exports="\t\n\v\f\r                 \u2028\u2029\ufeff"},1745:(t,e,r)=>{var n=r(6518),i=r(7476),o=r(9039),a=r(6346),s=r(8551),u=r(5610),c=r(8014),f=r(2293),l=a.ArrayBuffer,h=a.DataView,p=h.prototype,y=i(l.prototype.slice),v=i(p.getUint8),d=i(p.setUint8);n({target:"ArrayBuffer",proto:!0,unsafe:!0,forced:o((function(){return!new l(2).slice(1,void 0).byteLength}))},{slice:function(t,e){if(y&&void 0===e)return y(s(this),t);for(var r=s(this).byteLength,n=u(t,r),i=u(void 0===e?r:e,r),o=new(f(this,l))(c(i-n)),a=new h(this),p=new h(o),g=0;n{var n=r(6518),i=r(9213).every;n({target:"Array",proto:!0,forced:!r(4598)("every")},{every:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}})},2008:(t,e,r)=>{var n=r(6518),i=r(9213).filter;n({target:"Array",proto:!0,forced:!r(597)("filter")},{filter:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}})},113:(t,e,r)=>{var n=r(6518),i=r(9213).find,o=r(6469),a="find",s=!0;a in[]&&Array(1)[a]((function(){s=!1})),n({target:"Array",proto:!0,forced:s},{find:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}}),o(a)},6449:(t,e,r)=>{var n=r(6518),i=r(259),o=r(8981),a=r(6198),s=r(1291),u=r(1469);n({target:"Array",proto:!0},{flat:function(){var t=arguments.length?arguments[0]:void 0,e=o(this),r=a(e),n=u(e,0);return n.length=i(n,e,e,r,0,void 0===t?1:s(t)),n}})},1629:(t,e,r)=>{var n=r(6518),i=r(235);n({target:"Array",proto:!0,forced:[].forEach!==i},{forEach:i})},3418:(t,e,r)=>{var n=r(6518),i=r(7916);n({target:"Array",stat:!0,forced:!r(4428)((function(t){Array.from(t)}))},{from:i})},4423:(t,e,r)=>{var n=r(6518),i=r(9617).includes,o=r(9039),a=r(6469);n({target:"Array",proto:!0,forced:o((function(){return!Array(1).includes()}))},{includes:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}}),a("includes")},5276:(t,e,r)=>{var n=r(6518),i=r(7476),o=r(9617).indexOf,a=r(4598),s=i([].indexOf),u=!!s&&1/s([1],1,-0)<0;n({target:"Array",proto:!0,forced:u||!a("indexOf")},{indexOf:function(t){var e=arguments.length>1?arguments[1]:void 0;return u?s(this,t,e)||0:o(this,t,e)}})},4346:(t,e,r)=>{r(6518)({target:"Array",stat:!0},{isArray:r(4376)})},3792:(t,e,r)=>{var n=r(5397),i=r(6469),o=r(6269),a=r(1181),s=r(4913).f,u=r(1088),c=r(2529),f=r(6395),l=r(3724),h="Array Iterator",p=a.set,y=a.getterFor(h);t.exports=u(Array,"Array",(function(t,e){p(this,{type:h,target:n(t),index:0,kind:e})}),(function(){var t=y(this),e=t.target,r=t.index++;if(!e||r>=e.length)return t.target=void 0,c(void 0,!0);switch(t.kind){case"keys":return c(r,!1);case"values":return c(e[r],!1)}return c([r,e[r]],!1)}),"values");var v=o.Arguments=o.Array;if(i("keys"),i("values"),i("entries"),!f&&l&&"values"!==v.name)try{s(v,"name",{value:"values"})}catch(t){}},8598:(t,e,r)=>{var n=r(6518),i=r(9504),o=r(7055),a=r(5397),s=r(4598),u=i([].join);n({target:"Array",proto:!0,forced:o!==Object||!s("join",",")},{join:function(t){return u(a(this),void 0===t?",":t)}})},8921:(t,e,r)=>{var n=r(6518),i=r(8379);n({target:"Array",proto:!0,forced:i!==[].lastIndexOf},{lastIndexOf:i})},2062:(t,e,r)=>{var n=r(6518),i=r(9213).map;n({target:"Array",proto:!0,forced:!r(597)("map")},{map:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}})},4782:(t,e,r)=>{var n=r(6518),i=r(4376),o=r(3517),a=r(34),s=r(5610),u=r(6198),c=r(5397),f=r(4659),l=r(8227),h=r(597),p=r(7680),y=h("slice"),v=l("species"),d=Array,g=Math.max;n({target:"Array",proto:!0,forced:!y},{slice:function(t,e){var r,n,l,h=c(this),y=u(h),m=s(t,y),x=s(void 0===e?y:e,y);if(i(h)&&(r=h.constructor,(o(r)&&(r===d||i(r.prototype))||a(r)&&null===(r=r[v]))&&(r=void 0),r===d||void 0===r))return p(h,m,x);for(n=new(void 0===r?d:r)(g(x-m,0)),l=0;m{var n=r(6518),i=r(9504),o=r(9306),a=r(8981),s=r(6198),u=r(4606),c=r(655),f=r(9039),l=r(4488),h=r(4598),p=r(8834),y=r(3202),v=r(7388),d=r(9160),g=[],m=i(g.sort),x=i(g.push),b=f((function(){g.sort(void 0)})),w=f((function(){g.sort(null)})),S=h("sort"),E=!f((function(){if(v)return v<70;if(!(p&&p>3)){if(y)return!0;if(d)return d<603;var t,e,r,n,i="";for(t=65;t<76;t++){switch(e=String.fromCharCode(t),t){case 66:case 69:case 70:case 72:r=3;break;case 68:case 71:r=4;break;default:r=2}for(n=0;n<47;n++)g.push({k:e+n,v:r})}for(g.sort((function(t,e){return e.v-t.v})),n=0;nc(r)?1:-1}}(t)),r=s(i),n=0;n{var n=r(6518),i=r(8981),o=r(5610),a=r(1291),s=r(6198),u=r(4527),c=r(6837),f=r(1469),l=r(4659),h=r(4606),p=r(597)("splice"),y=Math.max,v=Math.min;n({target:"Array",proto:!0,forced:!p},{splice:function(t,e){var r,n,p,d,g,m,x=i(this),b=s(x),w=o(t,b),S=arguments.length;for(0===S?r=n=0:1===S?(r=0,n=b-w):(r=S-2,n=v(y(a(e),0),b-w)),c(b+r-n),p=f(x,n),d=0;db-n+r;d--)h(x,d-1)}else if(r>n)for(d=b-n;d>w;d--)m=d+r-1,(g=d+n-1)in x?x[m]=x[g]:h(x,m);for(d=0;d{r(6469)("flat")},4359:(t,e,r)=>{var n=r(6518),i=r(6346);n({global:!0,constructor:!0,forced:!r(7811)},{DataView:i.DataView})},8309:(t,e,r)=>{r(4359)},9572:(t,e,r)=>{var n=r(9297),i=r(6840),o=r(3640),a=r(8227)("toPrimitive"),s=Date.prototype;n(s,a)||i(s,a,o)},3288:(t,e,r)=>{var n=r(9504),i=r(6840),o=Date.prototype,a="Invalid Date",s="toString",u=n(o[s]),c=n(o.getTime);String(new Date(NaN))!==a&&i(o,s,(function(){var t=c(this);return t==t?u(this):a}))},3110:(t,e,r)=>{var n=r(6518),i=r(7751),o=r(8745),a=r(9565),s=r(9504),u=r(9039),c=r(4901),f=r(757),l=r(7680),h=r(6933),p=r(4495),y=String,v=i("JSON","stringify"),d=s(/./.exec),g=s("".charAt),m=s("".charCodeAt),x=s("".replace),b=s(1..toString),w=/[\uD800-\uDFFF]/g,S=/^[\uD800-\uDBFF]$/,E=/^[\uDC00-\uDFFF]$/,A=!p||u((function(){var t=i("Symbol")("stringify detection");return"[null]"!==v([t])||"{}"!==v({a:t})||"{}"!==v(Object(t))})),O=u((function(){return'"\\udf06\\ud834"'!==v("\udf06\ud834")||'"\\udead"'!==v("\udead")})),I=function(t,e){var r=l(arguments),n=h(e);if(c(n)||void 0!==t&&!f(t))return r[1]=function(t,e){if(c(n)&&(e=a(n,this,y(t),e)),!f(e))return e},o(v,null,r)},T=function(t,e,r){var n=g(r,e-1),i=g(r,e+1);return d(S,t)&&!d(E,i)||d(E,t)&&!d(S,n)?"\\u"+b(m(t,0),16):t};v&&n({target:"JSON",stat:!0,arity:3,forced:A||O},{stringify:function(t,e,r){var n=l(arguments),i=o(A?I:v,null,n);return O&&"string"==typeof i?x(i,w,T):i}})},8523:(t,e,r)=>{r(6468)("Map",(function(t){return function(){return t(this,arguments.length?arguments[0]:void 0)}}),r(6938))},6033:(t,e,r)=>{r(8523)},2892:(t,e,r)=>{var n=r(6518),i=r(6395),o=r(3724),a=r(4475),s=r(9167),u=r(9504),c=r(2796),f=r(9297),l=r(3167),h=r(1625),p=r(757),y=r(2777),v=r(9039),d=r(8480).f,g=r(7347).f,m=r(4913).f,x=r(1240),b=r(3802).trim,w="Number",S=a[w],E=s[w],A=S.prototype,O=a.TypeError,I=u("".slice),T=u("".charCodeAt),k=c(w,!S(" 0o1")||!S("0b1")||S("+0x1")),M=function(t){var e,r=arguments.length<1?0:S(function(t){var e=y(t,"number");return"bigint"==typeof e?e:function(t){var e,r,n,i,o,a,s,u,c=y(t,"number");if(p(c))throw new O("Cannot convert a Symbol value to a number");if("string"==typeof c&&c.length>2)if(c=b(c),43===(e=T(c,0))||45===e){if(88===(r=T(c,2))||120===r)return NaN}else if(48===e){switch(T(c,1)){case 66:case 98:n=2,i=49;break;case 79:case 111:n=8,i=55;break;default:return+c}for(a=(o=I(c,2)).length,s=0;si)return NaN;return parseInt(o,n)}return+c}(e)}(t));return h(A,e=this)&&v((function(){x(e)}))?l(Object(r),this,M):r};M.prototype=A,k&&!i&&(A.constructor=M),n({global:!0,constructor:!0,wrap:!0,forced:k},{Number:M});var _=function(t,e){for(var r,n=o?d(e):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,isFinite,isInteger,isNaN,isSafeInteger,parseFloat,parseInt,fromString,range".split(","),i=0;n.length>i;i++)f(e,r=n[i])&&!f(t,r)&&m(t,r,g(e,r))};i&&E&&_(s[w],E),(k||i)&&_(s[w],S)},7220:(t,e,r)=>{var n=r(6518),i=r(3904);n({target:"Number",stat:!0,forced:Number.parseFloat!==i},{parseFloat:i})},9868:(t,e,r)=>{var n=r(6518),i=r(9504),o=r(1291),a=r(1240),s=r(2333),u=r(9039),c=RangeError,f=String,l=Math.floor,h=i(s),p=i("".slice),y=i(1..toFixed),v=function(t,e,r){return 0===e?r:e%2==1?v(t,e-1,r*t):v(t*t,e/2,r)},d=function(t,e,r){for(var n=-1,i=r;++n<6;)i+=e*t[n],t[n]=i%1e7,i=l(i/1e7)},g=function(t,e){for(var r=6,n=0;--r>=0;)n+=t[r],t[r]=l(n/e),n=n%e*1e7},m=function(t){for(var e=6,r="";--e>=0;)if(""!==r||0===e||0!==t[e]){var n=f(t[e]);r=""===r?n:r+h("0",7-n.length)+n}return r};n({target:"Number",proto:!0,forced:u((function(){return"0.000"!==y(8e-5,3)||"1"!==y(.9,0)||"1.25"!==y(1.255,2)||"1000000000000000128"!==y(0xde0b6b3a7640080,0)}))||!u((function(){y({})}))},{toFixed:function(t){var e,r,n,i,s=a(this),u=o(t),l=[0,0,0,0,0,0],y="",x="0";if(u<0||u>20)throw new c("Incorrect fraction digits");if(s!=s)return"NaN";if(s<=-1e21||s>=1e21)return f(s);if(s<0&&(y="-",s=-s),s>1e-21)if(r=(e=function(t){for(var e=0,r=t;r>=4096;)e+=12,r/=4096;for(;r>=2;)e+=1,r/=2;return e}(s*v(2,69,1))-69)<0?s*v(2,-e,1):s/v(2,e,1),r*=4503599627370496,(e=52-e)>0){for(d(l,0,r),n=u;n>=7;)d(l,1e7,0),n-=7;for(d(l,v(10,n,1),0),n=e-1;n>=23;)g(l,1<<23),n-=23;g(l,1<0?y+((i=x.length)<=u?"0."+h("0",u-i)+x:p(x,0,i-u)+"."+p(x,i-u)):y+x}})},9904:(t,e,r)=>{r(6518)({target:"Object",stat:!0,sham:!r(3724)},{create:r(2360)})},4185:(t,e,r)=>{var n=r(6518),i=r(3724),o=r(4913).f;n({target:"Object",stat:!0,forced:Object.defineProperty!==o,sham:!i},{defineProperty:o})},3851:(t,e,r)=>{var n=r(6518),i=r(9039),o=r(5397),a=r(7347).f,s=r(3724);n({target:"Object",stat:!0,forced:!s||i((function(){a(1)})),sham:!s},{getOwnPropertyDescriptor:function(t,e){return a(o(t),e)}})},9773:(t,e,r)=>{var n=r(6518),i=r(4495),o=r(9039),a=r(3717),s=r(8981);n({target:"Object",stat:!0,forced:!i||o((function(){a.f(1)}))},{getOwnPropertySymbols:function(t){var e=a.f;return e?e(s(t)):[]}})},9432:(t,e,r)=>{var n=r(6518),i=r(8981),o=r(1072);n({target:"Object",stat:!0,forced:r(9039)((function(){o(1)}))},{keys:function(t){return o(i(t))}})},6099:(t,e,r)=>{var n=r(2140),i=r(6840),o=r(3179);n||i(Object.prototype,"toString",o,{unsafe:!0})},8459:(t,e,r)=>{var n=r(6518),i=r(3904);n({global:!0,forced:parseFloat!==i},{parseFloat:i})},4864:(t,e,r)=>{var n=r(3724),i=r(4475),o=r(9504),a=r(2796),s=r(3167),u=r(6699),c=r(2360),f=r(8480).f,l=r(1625),h=r(788),p=r(655),y=r(1034),v=r(8429),d=r(1056),g=r(6840),m=r(9039),x=r(9297),b=r(1181).enforce,w=r(7633),S=r(8227),E=r(3635),A=r(8814),O=S("match"),I=i.RegExp,T=I.prototype,k=i.SyntaxError,M=o(T.exec),_=o("".charAt),P=o("".replace),N=o("".indexOf),j=o("".slice),R=/^\?<[^\s\d!#%&*+<=>@^][^\s!#%&*+<=>@^]*>/,V=/a/g,D=/a/g,C=new I(V)!==V,F=v.MISSED_STICKY,z=v.UNSUPPORTED_Y;if(a("RegExp",n&&(!C||F||E||A||m((function(){return D[O]=!1,I(V)!==V||I(D)===D||"/a/i"!==String(I(V,"i"))}))))){for(var L=function(t,e){var r,n,i,o,a,f,v=l(T,this),d=h(t),g=void 0===e,m=[],w=t;if(!v&&d&&g&&t.constructor===L)return t;if((d||l(T,t))&&(t=t.source,g&&(e=y(w))),t=void 0===t?"":p(t),e=void 0===e?"":p(e),w=t,E&&"dotAll"in V&&(n=!!e&&N(e,"s")>-1)&&(e=P(e,/s/g,"")),r=e,F&&"sticky"in V&&(i=!!e&&N(e,"y")>-1)&&z&&(e=P(e,/y/g,"")),A&&(o=function(t){for(var e,r=t.length,n=0,i="",o=[],a=c(null),s=!1,u=!1,f=0,l="";n<=r;n++){if("\\"===(e=_(t,n)))e+=_(t,++n);else if("]"===e)s=!1;else if(!s)switch(!0){case"["===e:s=!0;break;case"("===e:M(R,j(t,n+1))&&(n+=2,u=!0),i+=e,f++;continue;case">"===e&&u:if(""===l||x(a,l))throw new k("Invalid capture group name");a[l]=!0,o[o.length]=[l,f],u=!1,l="";continue}u?l+=e:i+=e}return[i,o]}(t),t=o[0],m=o[1]),a=s(I(t,e),v?this:T,L),(n||i||m.length)&&(f=b(a),n&&(f.dotAll=!0,f.raw=L(function(t){for(var e,r=t.length,n=0,i="",o=!1;n<=r;n++)"\\"!==(e=_(t,n))?o||"."!==e?("["===e?o=!0:"]"===e&&(o=!1),i+=e):i+="[\\s\\S]":i+=e+_(t,++n);return i}(t),r)),i&&(f.sticky=!0),m.length&&(f.groups=m)),t!==w)try{u(a,"source",""===w?"(?:)":w)}catch(t){}return a},B=f(I),G=0;B.length>G;)d(L,I,B[G++]);T.constructor=L,L.prototype=T,g(i,"RegExp",L,{constructor:!0})}w("RegExp")},7495:(t,e,r)=>{var n=r(6518),i=r(7323);n({target:"RegExp",proto:!0,forced:/./.exec!==i},{exec:i})},8781:(t,e,r)=>{var n=r(350).PROPER,i=r(6840),o=r(8551),a=r(655),s=r(9039),u=r(1034),c="toString",f=RegExp.prototype,l=f[c],h=s((function(){return"/a/b"!==l.call({source:"a",flags:"b"})})),p=n&&l.name!==c;(h||p)&&i(f,c,(function(){var t=o(this);return"/"+a(t.source)+"/"+a(u(t))}),{unsafe:!0})},2405:(t,e,r)=>{r(6468)("Set",(function(t){return function(){return t(this,arguments.length?arguments[0]:void 0)}}),r(6938))},1415:(t,e,r)=>{r(2405)},4298:(t,e,r)=>{var n=r(6518),i=r(7240);n({target:"String",proto:!0,forced:r(3061)("fixed")},{fixed:function(){return i(this,"tt","","")}})},1699:(t,e,r)=>{var n=r(6518),i=r(9504),o=r(5749),a=r(7750),s=r(655),u=r(1436),c=i("".indexOf);n({target:"String",proto:!0,forced:!u("includes")},{includes:function(t){return!!~c(s(a(this)),s(o(t)),arguments.length>1?arguments[1]:void 0)}})},7764:(t,e,r)=>{var n=r(8183).charAt,i=r(655),o=r(1181),a=r(1088),s=r(2529),u="String Iterator",c=o.set,f=o.getterFor(u);a(String,"String",(function(t){c(this,{type:u,string:i(t),index:0})}),(function(){var t,e=f(this),r=e.string,i=e.index;return i>=r.length?s(void 0,!0):(t=n(r,i),e.index+=t.length,s(t,!1))}))},1761:(t,e,r)=>{var n=r(9565),i=r(9228),o=r(8551),a=r(4117),s=r(8014),u=r(655),c=r(7750),f=r(5966),l=r(7829),h=r(6682);i("match",(function(t,e,r){return[function(e){var r=c(this),i=a(e)?void 0:f(e,t);return i?n(i,e,r):new RegExp(e)[t](u(r))},function(t){var n=o(this),i=u(t),a=r(e,n,i);if(a.done)return a.value;if(!n.global)return h(n,i);var c=n.unicode;n.lastIndex=0;for(var f,p=[],y=0;null!==(f=h(n,i));){var v=u(f[0]);p[y]=v,""===v&&(n.lastIndex=l(i,s(n.lastIndex),c)),y++}return 0===y?null:p}]}))},5440:(t,e,r)=>{var n=r(8745),i=r(9565),o=r(9504),a=r(9228),s=r(9039),u=r(8551),c=r(4901),f=r(4117),l=r(1291),h=r(8014),p=r(655),y=r(7750),v=r(7829),d=r(5966),g=r(2478),m=r(6682),x=r(8227)("replace"),b=Math.max,w=Math.min,S=o([].concat),E=o([].push),A=o("".indexOf),O=o("".slice),I="$0"==="a".replace(/./,"$0"),T=!!/./[x]&&""===/./[x]("a","$0");a("replace",(function(t,e,r){var o=T?"$":"$0";return[function(t,r){var n=y(this),o=f(t)?void 0:d(t,x);return o?i(o,t,n,r):i(e,p(n),t,r)},function(t,i){var a=u(this),s=p(t);if("string"==typeof i&&-1===A(i,o)&&-1===A(i,"$<")){var f=r(e,a,s,i);if(f.done)return f.value}var y=c(i);y||(i=p(i));var d,x=a.global;x&&(d=a.unicode,a.lastIndex=0);for(var I,T=[];null!==(I=m(a,s))&&(E(T,I),x);)""===p(I[0])&&(a.lastIndex=v(s,h(a.lastIndex),d));for(var k,M="",_=0,P=0;P=_&&(M+=O(s,_,R)+N,_=R+j.length)}return M+O(s,_)}]}),!!s((function(){var t=/./;return t.exec=function(){var t=[];return t.groups={a:"7"},t},"7"!=="".replace(t,"$")}))||!I||T)},744:(t,e,r)=>{var n=r(9565),i=r(9504),o=r(9228),a=r(8551),s=r(4117),u=r(7750),c=r(2293),f=r(7829),l=r(8014),h=r(655),p=r(5966),y=r(6682),v=r(8429),d=r(9039),g=v.UNSUPPORTED_Y,m=Math.min,x=i([].push),b=i("".slice),w=!d((function(){var t=/(?:)/,e=t.exec;t.exec=function(){return e.apply(this,arguments)};var r="ab".split(t);return 2!==r.length||"a"!==r[0]||"b"!==r[1]})),S="c"==="abbc".split(/(b)*/)[1]||4!=="test".split(/(?:)/,-1).length||2!=="ab".split(/(?:ab)*/).length||4!==".".split(/(.?)(.?)/).length||".".split(/()()/).length>1||"".split(/.?/).length;o("split",(function(t,e,r){var i="0".split(void 0,0).length?function(t,r){return void 0===t&&0===r?[]:n(e,this,t,r)}:e;return[function(e,r){var o=u(this),a=s(e)?void 0:p(e,t);return a?n(a,e,o,r):n(i,h(o),e,r)},function(t,n){var o=a(this),s=h(t);if(!S){var u=r(i,o,s,n,i!==e);if(u.done)return u.value}var p=c(o,RegExp),v=o.unicode,d=(o.ignoreCase?"i":"")+(o.multiline?"m":"")+(o.unicode?"u":"")+(g?"g":"y"),w=new p(g?"^(?:"+o.source+")":o,d),E=void 0===n?4294967295:n>>>0;if(0===E)return[];if(0===s.length)return null===y(w,s)?[s]:[];for(var A=0,O=0,I=[];O{var n,i=r(6518),o=r(7476),a=r(7347).f,s=r(8014),u=r(655),c=r(5749),f=r(7750),l=r(1436),h=r(6395),p=o("".slice),y=Math.min,v=l("startsWith");i({target:"String",proto:!0,forced:!(!h&&!v&&(n=a(String.prototype,"startsWith"),n&&!n.writable)||v)},{startsWith:function(t){var e=u(f(this));c(t);var r=s(y(arguments.length>1?arguments[1]:void 0,e.length)),n=u(t);return p(e,r,r+n.length)===n}})},6761:(t,e,r)=>{var n=r(6518),i=r(4475),o=r(9565),a=r(9504),s=r(6395),u=r(3724),c=r(4495),f=r(9039),l=r(9297),h=r(1625),p=r(8551),y=r(5397),v=r(6969),d=r(655),g=r(6980),m=r(2360),x=r(1072),b=r(8480),w=r(298),S=r(3717),E=r(7347),A=r(4913),O=r(6801),I=r(8773),T=r(6840),k=r(2106),M=r(5745),_=r(6119),P=r(421),N=r(3392),j=r(8227),R=r(1951),V=r(511),D=r(8242),C=r(687),F=r(1181),z=r(9213).forEach,L=_("hidden"),B="Symbol",G="prototype",U=F.set,H=F.getterFor(B),W=Object[G],Y=i.Symbol,$=Y&&Y[G],q=i.RangeError,K=i.TypeError,X=i.QObject,J=E.f,Z=A.f,Q=w.f,tt=I.f,et=a([].push),rt=M("symbols"),nt=M("op-symbols"),it=M("wks"),ot=!X||!X[G]||!X[G].findChild,at=function(t,e,r){var n=J(W,e);n&&delete W[e],Z(t,e,r),n&&t!==W&&Z(W,e,n)},st=u&&f((function(){return 7!==m(Z({},"a",{get:function(){return Z(this,"a",{value:7}).a}})).a}))?at:Z,ut=function(t,e){var r=rt[t]=m($);return U(r,{type:B,tag:t,description:e}),u||(r.description=e),r},ct=function(t,e,r){t===W&&ct(nt,e,r),p(t);var n=v(e);return p(r),l(rt,n)?(r.enumerable?(l(t,L)&&t[L][n]&&(t[L][n]=!1),r=m(r,{enumerable:g(0,!1)})):(l(t,L)||Z(t,L,g(1,m(null))),t[L][n]=!0),st(t,n,r)):Z(t,n,r)},ft=function(t,e){p(t);var r=y(e),n=x(r).concat(yt(r));return z(n,(function(e){u&&!o(lt,r,e)||ct(t,e,r[e])})),t},lt=function(t){var e=v(t),r=o(tt,this,e);return!(this===W&&l(rt,e)&&!l(nt,e))&&(!(r||!l(this,e)||!l(rt,e)||l(this,L)&&this[L][e])||r)},ht=function(t,e){var r=y(t),n=v(e);if(r!==W||!l(rt,n)||l(nt,n)){var i=J(r,n);return!i||!l(rt,n)||l(r,L)&&r[L][n]||(i.enumerable=!0),i}},pt=function(t){var e=Q(y(t)),r=[];return z(e,(function(t){l(rt,t)||l(P,t)||et(r,t)})),r},yt=function(t){var e=t===W,r=Q(e?nt:y(t)),n=[];return z(r,(function(t){!l(rt,t)||e&&!l(W,t)||et(n,rt[t])})),n};c||(T($=(Y=function(){if(h($,this))throw new K("Symbol is not a constructor");var t=arguments.length&&void 0!==arguments[0]?d(arguments[0]):void 0,e=N(t),r=function(t){var n=void 0===this?i:this;n===W&&o(r,nt,t),l(n,L)&&l(n[L],e)&&(n[L][e]=!1);var a=g(1,t);try{st(n,e,a)}catch(t){if(!(t instanceof q))throw t;at(n,e,a)}};return u&&ot&&st(W,e,{configurable:!0,set:r}),ut(e,t)})[G],"toString",(function(){return H(this).tag})),T(Y,"withoutSetter",(function(t){return ut(N(t),t)})),I.f=lt,A.f=ct,O.f=ft,E.f=ht,b.f=w.f=pt,S.f=yt,R.f=function(t){return ut(j(t),t)},u&&(k($,"description",{configurable:!0,get:function(){return H(this).description}}),s||T(W,"propertyIsEnumerable",lt,{unsafe:!0}))),n({global:!0,constructor:!0,wrap:!0,forced:!c,sham:!c},{Symbol:Y}),z(x(it),(function(t){V(t)})),n({target:B,stat:!0,forced:!c},{useSetter:function(){ot=!0},useSimple:function(){ot=!1}}),n({target:"Object",stat:!0,forced:!c,sham:!u},{create:function(t,e){return void 0===e?m(t):ft(m(t),e)},defineProperty:ct,defineProperties:ft,getOwnPropertyDescriptor:ht}),n({target:"Object",stat:!0,forced:!c},{getOwnPropertyNames:pt}),D(),C(Y,B),P[L]=!0},9463:(t,e,r)=>{var n=r(6518),i=r(3724),o=r(4475),a=r(9504),s=r(9297),u=r(4901),c=r(1625),f=r(655),l=r(2106),h=r(7740),p=o.Symbol,y=p&&p.prototype;if(i&&u(p)&&(!("description"in y)||void 0!==p().description)){var v={},d=function(){var t=arguments.length<1||void 0===arguments[0]?void 0:f(arguments[0]),e=c(y,this)?new p(t):void 0===t?p():p(t);return""===t&&(v[e]=!0),e};h(d,p),d.prototype=y,y.constructor=d;var g="Symbol(description detection)"===String(p("description detection")),m=a(y.valueOf),x=a(y.toString),b=/^Symbol\((.*)\)[^)]+$/,w=a("".replace),S=a("".slice);l(y,"description",{configurable:!0,get:function(){var t=m(this);if(s(v,t))return"";var e=x(t),r=g?S(e,7,-1):w(e,b,"$1");return""===r?void 0:r}}),n({global:!0,constructor:!0,forced:!0},{Symbol:d})}},1510:(t,e,r)=>{var n=r(6518),i=r(7751),o=r(9297),a=r(655),s=r(5745),u=r(1296),c=s("string-to-symbol-registry"),f=s("symbol-to-string-registry");n({target:"Symbol",stat:!0,forced:!u},{for:function(t){var e=a(t);if(o(c,e))return c[e];var r=i("Symbol")(e);return c[e]=r,f[r]=e,r}})},2259:(t,e,r)=>{r(511)("iterator")},2675:(t,e,r)=>{r(6761),r(1510),r(7812),r(3110),r(9773)},7812:(t,e,r)=>{var n=r(6518),i=r(9297),o=r(757),a=r(6823),s=r(5745),u=r(1296),c=s("symbol-to-string-registry");n({target:"Symbol",stat:!0,forced:!u},{keyFor:function(t){if(!o(t))throw new TypeError(a(t)+" is not a symbol");if(i(c,t))return c[t]}})},5700:(t,e,r)=>{var n=r(511),i=r(8242);n("toPrimitive"),i()},1630:(t,e,r)=>{var n=r(9504),i=r(4644),o=n(r(7029)),a=i.aTypedArray;(0,i.exportTypedArrayMethod)("copyWithin",(function(t,e){return o(a(this),t,e,arguments.length>2?arguments[2]:void 0)}))},2170:(t,e,r)=>{var n=r(4644),i=r(9213).every,o=n.aTypedArray;(0,n.exportTypedArrayMethod)("every",(function(t){return i(o(this),t,arguments.length>1?arguments[1]:void 0)}))},5044:(t,e,r)=>{var n=r(4644),i=r(4373),o=r(5854),a=r(6955),s=r(9565),u=r(9504),c=r(9039),f=n.aTypedArray,l=n.exportTypedArrayMethod,h=u("".slice);l("fill",(function(t){var e=arguments.length;f(this);var r="Big"===h(a(this),0,3)?o(t):+t;return s(i,this,r,e>1?arguments[1]:void 0,e>2?arguments[2]:void 0)}),c((function(){var t=0;return new Int8Array(2).fill({valueOf:function(){return t++}}),1!==t})))},1920:(t,e,r)=>{var n=r(4644),i=r(9213).filter,o=r(6357),a=n.aTypedArray;(0,n.exportTypedArrayMethod)("filter",(function(t){var e=i(a(this),t,arguments.length>1?arguments[1]:void 0);return o(this,e)}))},9955:(t,e,r)=>{var n=r(4644),i=r(9213).findIndex,o=n.aTypedArray;(0,n.exportTypedArrayMethod)("findIndex",(function(t){return i(o(this),t,arguments.length>1?arguments[1]:void 0)}))},1694:(t,e,r)=>{var n=r(4644),i=r(9213).find,o=n.aTypedArray;(0,n.exportTypedArrayMethod)("find",(function(t){return i(o(this),t,arguments.length>1?arguments[1]:void 0)}))},9833:(t,e,r)=>{r(5823)("Float64",(function(t){return function(e,r,n){return t(this,e,r,n)}}))},3206:(t,e,r)=>{var n=r(4644),i=r(9213).forEach,o=n.aTypedArray;(0,n.exportTypedArrayMethod)("forEach",(function(t){i(o(this),t,arguments.length>1?arguments[1]:void 0)}))},4496:(t,e,r)=>{var n=r(4644),i=r(9617).includes,o=n.aTypedArray;(0,n.exportTypedArrayMethod)("includes",(function(t){return i(o(this),t,arguments.length>1?arguments[1]:void 0)}))},6651:(t,e,r)=>{var n=r(4644),i=r(9617).indexOf,o=n.aTypedArray;(0,n.exportTypedArrayMethod)("indexOf",(function(t){return i(o(this),t,arguments.length>1?arguments[1]:void 0)}))},2887:(t,e,r)=>{var n=r(4475),i=r(9039),o=r(9504),a=r(4644),s=r(3792),u=r(8227)("iterator"),c=n.Uint8Array,f=o(s.values),l=o(s.keys),h=o(s.entries),p=a.aTypedArray,y=a.exportTypedArrayMethod,v=c&&c.prototype,d=!i((function(){v[u].call([1])})),g=!!v&&v.values&&v[u]===v.values&&"values"===v.values.name,m=function(){return f(p(this))};y("entries",(function(){return h(p(this))}),d),y("keys",(function(){return l(p(this))}),d),y("values",m,d||!g,{name:"values"}),y(u,m,d||!g,{name:"values"})},9369:(t,e,r)=>{var n=r(4644),i=r(9504),o=n.aTypedArray,a=n.exportTypedArrayMethod,s=i([].join);a("join",(function(t){return s(o(this),t)}))},6812:(t,e,r)=>{var n=r(4644),i=r(8745),o=r(8379),a=n.aTypedArray;(0,n.exportTypedArrayMethod)("lastIndexOf",(function(t){var e=arguments.length;return i(o,a(this),e>1?[t,arguments[1]]:[t])}))},8995:(t,e,r)=>{var n=r(4644),i=r(9213).map,o=r(1412),a=n.aTypedArray;(0,n.exportTypedArrayMethod)("map",(function(t){return i(a(this),t,arguments.length>1?arguments[1]:void 0,(function(t,e){return new(o(t))(e)}))}))},6072:(t,e,r)=>{var n=r(4644),i=r(926).right,o=n.aTypedArray;(0,n.exportTypedArrayMethod)("reduceRight",(function(t){var e=arguments.length;return i(o(this),t,e,e>1?arguments[1]:void 0)}))},1575:(t,e,r)=>{var n=r(4644),i=r(926).left,o=n.aTypedArray;(0,n.exportTypedArrayMethod)("reduce",(function(t){var e=arguments.length;return i(o(this),t,e,e>1?arguments[1]:void 0)}))},8747:(t,e,r)=>{var n=r(4644),i=n.aTypedArray,o=n.exportTypedArrayMethod,a=Math.floor;o("reverse",(function(){for(var t,e=this,r=i(e).length,n=a(r/2),o=0;o{var n=r(4475),i=r(9565),o=r(4644),a=r(6198),s=r(8229),u=r(8981),c=r(9039),f=n.RangeError,l=n.Int8Array,h=l&&l.prototype,p=h&&h.set,y=o.aTypedArray,v=o.exportTypedArrayMethod,d=!c((function(){var t=new Uint8ClampedArray(2);return i(p,t,{length:1,0:3},1),3!==t[1]})),g=d&&o.NATIVE_ARRAY_BUFFER_VIEWS&&c((function(){var t=new l(2);return t.set(1),t.set("2",1),0!==t[0]||2!==t[1]}));v("set",(function(t){y(this);var e=s(arguments.length>1?arguments[1]:void 0,1),r=u(t);if(d)return i(p,this,r,e);var n=this.length,o=a(r),c=0;if(o+e>n)throw new f("Wrong length");for(;c{var n=r(4644),i=r(1412),o=r(9039),a=r(7680),s=n.aTypedArray;(0,n.exportTypedArrayMethod)("slice",(function(t,e){for(var r=a(s(this),t,e),n=i(this),o=0,u=r.length,c=new n(u);u>o;)c[o]=r[o++];return c}),o((function(){new Int8Array(1).slice()})))},7301:(t,e,r)=>{var n=r(4644),i=r(9213).some,o=n.aTypedArray;(0,n.exportTypedArrayMethod)("some",(function(t){return i(o(this),t,arguments.length>1?arguments[1]:void 0)}))},373:(t,e,r)=>{var n=r(4475),i=r(7476),o=r(9039),a=r(9306),s=r(4488),u=r(4644),c=r(8834),f=r(3202),l=r(7388),h=r(9160),p=u.aTypedArray,y=u.exportTypedArrayMethod,v=n.Uint16Array,d=v&&i(v.prototype.sort),g=!(!d||o((function(){d(new v(2),null)}))&&o((function(){d(new v(2),{})}))),m=!!d&&!o((function(){if(l)return l<74;if(c)return c<67;if(f)return!0;if(h)return h<602;var t,e,r=new v(516),n=Array(516);for(t=0;t<516;t++)e=t%4,r[t]=515-t,n[t]=t-2*e+3;for(d(r,(function(t,e){return(t/4|0)-(e/4|0)})),t=0;t<516;t++)if(r[t]!==n[t])return!0}));y("sort",(function(t){return void 0!==t&&a(t),m?d(this,t):s(p(this),function(t){return function(e,r){return void 0!==t?+t(e,r)||0:r!=r?-1:e!=e?1:0===e&&0===r?1/e>0&&1/r<0?1:-1:e>r}}(t))}),!m||g)},6614:(t,e,r)=>{var n=r(4644),i=r(8014),o=r(5610),a=r(1412),s=n.aTypedArray;(0,n.exportTypedArrayMethod)("subarray",(function(t,e){var r=s(this),n=r.length,u=o(t,n);return new(a(r))(r.buffer,r.byteOffset+u*r.BYTES_PER_ELEMENT,i((void 0===e?n:o(e,n))-u))}))},1405:(t,e,r)=>{var n=r(4475),i=r(8745),o=r(4644),a=r(9039),s=r(7680),u=n.Int8Array,c=o.aTypedArray,f=o.exportTypedArrayMethod,l=[].toLocaleString,h=!!u&&a((function(){l.call(new u(1))}));f("toLocaleString",(function(){return i(l,h?s(c(this)):c(this),s(arguments))}),a((function(){return[1,2].toLocaleString()!==new u([1,2]).toLocaleString()}))||!a((function(){u.prototype.toLocaleString.call([1,2])})))},3684:(t,e,r)=>{var n=r(4644).exportTypedArrayMethod,i=r(9039),o=r(4475),a=r(9504),s=o.Uint8Array,u=s&&s.prototype||{},c=[].toString,f=a([].join);i((function(){c.call({})}))&&(c=function(){return f(this)});var l=u.toString!==c;n("toString",c,l)},3500:(t,e,r)=>{var n=r(4475),i=r(7400),o=r(9296),a=r(235),s=r(6699),u=function(t){if(t&&t.forEach!==a)try{s(t,"forEach",a)}catch(e){t.forEach=a}};for(var c in i)i[c]&&u(n[c]&&n[c].prototype);u(o)},2953:(t,e,r)=>{var n=r(4475),i=r(7400),o=r(9296),a=r(3792),s=r(6699),u=r(687),c=r(8227)("iterator"),f=a.values,l=function(t,e){if(t){if(t[c]!==f)try{s(t,c,f)}catch(e){t[c]=f}if(u(t,e,!0),i[e])for(var r in a)if(t[r]!==a[r])try{s(t,r,a[r])}catch(e){t[r]=a[r]}}};for(var h in i)l(n[h]&&n[h].prototype,h);l(o,"DOMTokenList")}},n={};function i(t){var e=n[t];if(void 0!==e)return e.exports;var o=n[t]={exports:{}};return r[t].call(o.exports,o,o.exports,i),o.exports}i.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return i.d(e,{a:e}),e},i.d=(t,e)=>{for(var r in e)i.o(e,r)&&!i.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),i.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var o={};return(()=>{i.r(o),i.d(o,{factory:()=>wt}),i(2675),i(9463),i(2259),i(5700),i(1629),i(4423),i(3792),i(8598),i(9572),i(6033),i(2892),i(7220),i(9868),i(4185),i(6099),i(7495),i(1699),i(7764),i(5440),i(3500),i(2953);var t=i(3893);function e(){var t,e,r,n=(r=(e=navigator.userAgent).match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i)||[],/trident/i.test(r[1])?"IE "+((t=/\brv[ :]+(\d+)/g.exec(e)||[])[1]||""):"Chrome"===r[1]&&null!==(t=e.match(/\b(OPR|Edge)\/(\d+)/))?t.slice(1).join(" ").replace("OPR","Opera"):(r=r[2]?[r[1],r[2]]:[navigator.appName,navigator.appVersion,"-?"],null!==(t=e.match(/version\/(\d+)/i))&&r.splice(1,1,t[1]),r.join(" ")));return"IE 11"==n||"MSIE"===n.substring(0,4)}function r(t){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r(t)}function n(t,e){for(var r=0;r"},zoom_off:{class:"drop",unclass:"neutral",tooltip:"deactivate pan/zoom",icon:""}},onclick:function(r){var n,i=t.select(this);e.on?(e.zoomOff(),n=r.zoom_on):(e.zoomOn(),n=r.zoom_off),i.attr("title",n.tooltip).classed(n.class,!0).classed(n.unclass,!1).html(n.icon)}},{key:"zoom_rect",block:"zoom",class:"neutral",tooltip:"zoom with rectangle",icon:"",onclick:function(){e.zoomRect()}},{key:"zoom_reset",block:"zoom",class:"neutral",tooltip:"reset pan/zoom",icon:"",onclick:function(){e.zoomIdentity()}}]}},{key:"zoomOn",value:function(){if(!this.on){this.on=!0;var e=t.select("#"+this.svgid+"_rootg");t.select("#"+this.svgid).call(this.zoomer.on("start",(function(){e.style("cursor","move")})).on("zoom",(function(){e.attr("transform",t.event.transform)})).on("end",(function(){e.style("cursor","auto")})))}}},{key:"zoomIdentity",value:function(){var e=t.zoomTransform(t.select("#"+this.svgid+"_rootg").node());if(1!==e.k||0!==e.x||0!==e.y){var r=this.on;r||this.zoomOn();var n=this;t.select("#"+this.svgid).transition().duration(this.duration).on("end",(function(){r||n.zoomOff()})).call(this.zoomer.transform,t.zoomIdentity)}}},{key:"zoomOff",value:function(){this.on&&(this.on=!1,t.select("#"+this.svgid).on(".zoom",null))}},{key:"zoomRect",value:function(){var e=this.on;e||this.zoomOn();var r=t.select("#"+this.svgid),n=t.select("#"+this.svgid+"_rootg"),i=this,o=function(){var e,r=new DOMRect,n={start:function(){},draw:function(){},end:function(){}};function i(i){var o,a,s=i.append("g").attr("class","dragrect").append("rect"),u=t.drag().on("start",(function(){o=null,a=null,n.start()})).on("drag",(function(){var e=t.mouse(this)[0],i=t.mouse(this)[1];o?(a.x=e,a.y=i):(o=new DOMPoint(e,i),a=new DOMPoint(e,i));var u=Math.min(o.x,a.x),c=Math.max(o.x,a.x),f=Math.min(o.y,a.y),l=Math.max(o.y,a.y);r.x=u,r.y=f,r.width=c-u,r.height=l-f,s.attr("x",r.x),s.attr("y",r.y),s.attr("width",r.width),s.attr("height",r.height),n.draw()})).on("end",(function(){s.attr("display","none"),n.end()}));e.call(u)}return i.on=function(t,e){return arguments.length?1===arguments.length?n[t]:(["start","draw","end"].indexOf(t)>-1&&(n[t]=e),i):n},i.targetArea=function(t){return arguments.length?(e=t,i):e},i.rect=function(){return r},i}();try{n.call(o.targetArea(n).on("start",(function(){n.style("cursor","zoom-in")})).on("end",(function(){try{n.style("cursor","auto"),n.on(".dragstart",null).on(".drag",null).on(".dragend",null),n.selectAll("g.dragrect").remove();var a=o.rect();if(a.width>=10&&a.height>=10){var s=a.x+a.width/2,u=a.y+a.height/2,c=n.node().getBBox(),f=c.x+c.width/2,l=c.y+c.height/2,h=c.width/c.height;a.height>a.width?(a.width=a.height*h,a.x=s-a.width/2):(a.height=a.width/h,a.y=u-a.height/2);var p=Math.max(Math.min(c.width/a.width,i.max),i.min);a.width=c.width/p,a.height=c.height/p,a.x=s-a.width/2,a.y=u-a.height/2;var y=(f-s-(c.width-a.width)/2)*p,v=(l-u-(c.height-a.height)/2)*p;r.transition().duration(i.duration).on("end",(function(){e||i.zoomOff()})).call(i.zoomer.transform,t.zoomIdentity.translate(y,v).scale(p))}}catch(t){console.error(t)}})))}catch(t){console.error(t)}}}],r&&c(e.prototype,r),Object.defineProperty(e,"prototype",{writable:!1}),e;var e,r}();function h(t){return h="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},h(t)}function p(t,e){for(var r=0;r=1)return x(t,r);var o=((e.y-t.y)*(r.x-e.x)-(e.x-t.x)*(r.y-e.y))/n;return Math.abs(o)*Math.sqrt(n)}function w(t,e){var r,n,i,o,a,s,u,c,f,l,h,p,y,v,d=t.x,g=t.y,m=t.x+t.width,x=t.y+t.height;if(e.find((function(t){return t.x>=d&&t.x<=m&&t.y>=g&&t.y<=x})))return!0;if(1===e.length&&e[0].r){var b=e[0],w=Math.abs(b.x-(t.x+t.width/2)),S=Math.abs(b.y-(t.y+t.height/2));return!(w>t.width/2+b.r||S>t.height/2+b.r||!(w<=t.width/2||S<=t.height/2||(w-t.width/2^S-t.height/2+2^2)<=(2^b.r)))}if(e.length>1)for(r=0;r0&&y<1&&v>0&&v<1&&(h=!0)),h)return!0;return!1}function S(t){var e,r,n,i,o,a,s=new RegExp("([\\d\\.]+) ([\\d\\.]+)","g");if(t instanceof SVGRect||t instanceof DOMRect)return[new DOMPoint(t.x,t.y),new DOMPoint(t.x+t.width,t.y),new DOMPoint(t.x+t.width,t.y+t.height),new DOMPoint(t.x,t.y+t.height)];if(t instanceof SVGRectElement||t instanceof SVGImageElement)return[new DOMPoint(t.x.baseVal.value,t.y.baseVal.value),new DOMPoint(t.x.baseVal.value+t.width.baseVal.value,t.y.baseVal.value),new DOMPoint(t.x.baseVal.value+t.width.baseVal.value,t.y.baseVal.value+t.height.baseVal.value),new DOMPoint(t.x.baseVal.value,t.y.baseVal.value+t.height.baseVal.value)];if(t instanceof SVGCircleElement)return(r=new DOMPoint(t.cx.baseVal.value,t.cy.baseVal.value)).r=t.r.baseVal.value,[r];if(t instanceof SVGLineElement)return(e=[new DOMPoint(t.x1.baseVal.value,t.y1.baseVal.value),new DOMPoint(t.x2.baseVal.value,t.y2.baseVal.value)]).shape="polyline",e;if(t instanceof SVGPolylineElement||t instanceof SVGPolygonElement){for(e=[],n=t.points,i=0;i3&&void 0!==arguments[3]?arguments[3]:"#ff000033",o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:"#ff0000",a=document.getElementById(r);if(Array.isArray(t)&&1===t.length&&(t=t[0]),a?n=a.localName:(n=t.shape||"polygon",t instanceof SVGPoint||t instanceof DOMPoint?n="circle":(t instanceof SVGRect||t instanceof DOMRect)&&(n="rect"),(a=document.createElementNS("http://www.w3.org/2000/svg",n)).setAttribute("id",r),"polyline"!==n&&a.setAttribute("fill",i),a.setAttribute("stroke",o),a.setAttribute("style","pointer-events: none;"),e.appendChild(a)),"circle"===n)a.setAttribute("cx",t.x),a.setAttribute("cy",t.y),a.setAttribute("r",t.r||"3pt");else if("rect"===n)a.setAttribute("x",t.x),a.setAttribute("y",t.y),a.setAttribute("width",t.width),a.setAttribute("height",t.height);else if("polygon"===n||"polyline"===n){var s="";t.forEach((function(t){s+=t.x+" "+t.y+" "})),a.setAttribute("points",s)}return a}i(113),i(1745),i(8309),i(3288),i(9904),i(3851),i(8459),i(4864),i(8781),i(744),i(9833),i(1630),i(2170),i(5044),i(1920),i(1694),i(9955),i(3206),i(4496),i(6651),i(2887),i(9369),i(6812),i(8995),i(1575),i(6072),i(8747),i(8845),i(9423),i(7301),i(373),i(6614),i(1405),i(3684),window.DOMPoint=window.DOMPoint||y((function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:1;d(this,t),this.x=e,this.y=r,this.z=n,this.w=i})),window.DOMPoint.prototype.matrixTransform=window.DOMPoint.prototype.matrixTransform||function(t){return(t.is2D||t instanceof SVGMatrix)&&0===this.z&&1===this.w?new DOMPoint(this.x*t.a+this.y*t.c+t.e,this.x*t.b+this.y*t.d+t.f,0,1):new DOMPoint(this.x*t.m11+this.y*t.m21+this.z*t.m31+this.w*t.m41,this.x*t.m12+this.y*t.m22+this.z*t.m32+this.w*t.m42,this.x*t.m13+this.y*t.m23+this.z*t.m33+this.w*t.m43,this.x*t.m14+this.y*t.m24+this.z*t.m34+this.w*t.m44)};for(var T=function(){return y((function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0;d(this,t),this.x=e,this.y=r,this.width=n,this.height=i}),[{key:"top",get:function(){return this.y}},{key:"left",get:function(){return this.x}},{key:"right",get:function(){return this.x+this.width}},{key:"bottom",get:function(){return this.y+this.height}}])}(),k=0,M=["top","right","bottom","left"];k0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return this[N]=F([1,0,0,0,0,1,0,0,0,0,1,0,t,e,r,1],this[N]),0!==r&&(this[j]=!1),this}},{key:"scale",value:function(t,e,r,n,i,o){return C(this[N]).scaleSelf(t,e,r,n,i,o)}},{key:"scale3d",value:function(t,e,r,n){return C(this[N]).scale3dSelf(t,e,r,n)}},{key:"scale3dSelf",value:function(t,e,r,n){return this.scaleSelf(t,t,t,e,r,n)}},{key:"scaleSelf",value:function(t,e,r,n,i,o){return"number"!=typeof n&&(n=0),"number"!=typeof i&&(i=0),"number"!=typeof o&&(o=0),this.translateSelf(n,i,o),"number"!=typeof t&&(t=1),"number"!=typeof e&&(e=t),"number"!=typeof r&&(r=1),this[N]=F([t,0,0,0,0,e,0,0,0,0,r,0,0,0,0,1],this[N]),this.translateSelf(-n,-i,-o),1===r&&0===o||(this[j]=!1),this}},{key:"inverse",value:function(){return C(this[N]).invertSelf()}},{key:"invertSelf",value:function(){if(!this[j])throw new Error("3D matrix inversion is not implemented.");var e=this[N][0]*this[N][5]-this[N][1]*this[N][4];if(0!==e){var r=new t;return r.a=this[N][5]/e,r.b=-this[N][1]/e,r.c=-this[N][4]/e,r.d=this[N][0]/e,r.e=(this[N][4]*this[N][13]-this[N][5]*this[N][12])/e,r.f=(this[N][1]*this[N][12]-this[N][0]*this[N][13])/e,r}this[j]=!1,this[N]=[NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN]}}])}(),L=0,B=["a","b","c","d","e","f","m11","m12","m13","m14","m21","m22","m23","m24","m31","m32","m33","m34","m41","m42","m43","m44","is2D","isIdentity"];L=u&&y.push(Math.max(l.x,n.x+this.offx)),d>=u&&y.push(Math.min(h.x-u,n.x-this.offx-u)),y.push(Math.max(l.x,Math.min(h.x,n.x+u/2)-u));var x=[],b=h.y-(n.y+this.offy),w=n.y-this.offy-l.y;b>=c&&x.push(Math.max(l.y,n.y+this.offy)),w>=c&&x.push(Math.min(h.y-c,n.y-this.offy-c)),x.push(Math.max(l.y,Math.min(h.y,n.y+c/2)-c));var S=[];y.forEach((function(t){x.forEach((function(e){S.push(new DOMRect(t,e,u,c))}))}));var E=S.find((function(t){return r=p,!((e=t).x<=r.x&&e.x+e.width>=r.x+r.width&&e.y<=r.y&&e.y+e.height>=r.y+r.height);var e,r}));E||(E=S[0]),n.x=E.x,n.y=E.y}else n=new DOMPoint(this.offx,this.offy),"doc"==this.placement&&(i=m(s),n=n.matrixTransform(i));return n}}])&&W(e.prototype,r),Object.defineProperty(e,"prototype",{writable:!1}),e;var e,r}();function q(t){return q="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},q(t)}function K(t,e){for(var r=0;r",onclick:function(){t.lasso(!0)}},{key:"lasso_deselect",block:"selection",class:"drop",tooltip:"lasso deselection",icon:"",onclick:function(){t.lasso(!1)}}]}},{key:"clear",value:function(){this.setSelected([])}},{key:"isValidTarget",value:function(t){return t instanceof SVGGraphicsElement&&!(t instanceof SVGSVGElement)&&t.hasAttribute(this.attrName)}},{key:"applyOn",value:function(t,e){try{if(this.isValidTarget(t)){var r=t.getAttribute(this.attrName),n=Array.from(this.dataSelected),i=n.indexOf(r);return"multiple"==this.type?i<0?n.push(r):n.splice(i,1):n=i<0?[r]:[],this.setSelected(n),!0}}catch(t){console.error(t)}return!1}},{key:"setSelected",value:function(t){this.dataSelected.length===t.length&&this.dataSelected.every((function(e){return t.includes(e)}))||(this.dataSelected=t,this.refreshSelected(),this.shinyInputId&&Shiny.onInputChange(this.shinyInputId,this.dataSelected))}},{key:"refreshSelected",value:function(){var e,r,n;this.nodeIds.forEach((function(i){(e=document.getElementById(i))&&(r=this.dataSelected.includes(e.getAttribute(this.attrName)),(n=t.select(e)).classed(this.clsName,r),this.invClsName&&(this.dataSelected.length?n.classed(this.invClsName,!r):n.classed(this.invClsName,!1)))}),this)}},{key:"lasso",value:function(e){var r=t.select("#"+this.svgid+"_rootg"),n=this,i=t.lasso();try{i=i.closePathSelect(!0).closePathDistance(100).items(r.selectAll("*["+this.attrName+"]")).targetArea(r).on("start",(function(){r.style("cursor","crosshair")})).on("draw",(function(){})).on("end",(function(){try{r.style("cursor","auto"),r.on(".dragstart",null).on(".drag",null).on(".dragend",null),r.selectAll("g.lasso").remove();var t=Array.from(n.dataSelected);i.selectedItems().each((function(r,i){var o=this.getAttribute(n.attrName),a=t.indexOf(o);a<0&&e?t.push(o):a>=0&&!e&&t.splice(a,1)})),n.setSelected(t)}catch(t){console.error(t)}})),r.call(i)}catch(t){console.error(t)}}}])&&Q(e.prototype,r),Object.defineProperty(e,"prototype",{writable:!1}),e;var e,r}();function rt(t){return rt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},rt(t)}function nt(t,e){for(var r=0;rr.x&&e.yr.y;var e,r}))}if(c.length&&o.checkIntersection){var l=a.getCTM();u=u.map((function(t){return t.matrixTransform(l)})),s=O(u,o),c=c.filter((function(t){return o.checkIntersection(t,s)}))}else c.length&&(c=c.filter((function(t){return w(s,t.gpoints)})));var h=null;if(1===c.length)h=c[0];else if(c.length){var p=1/0,y=1/0;c.forEach((function(t){var e,r;t instanceof SVGCircleElement?(e=i,r=t.gpoints[0],p=x(e,r)-r.r):p=function(t,e){var r,n,i=1/0;if(e.length>1)for(var o=0;o",onclick:function(){t.save_as_png()}}]}},{key:"save_as_png",value:function(){this.fonts||(this.fonts=function(){var t=["woff","ttf","otf","woff2","eot"],e={woff2:"font/woff2",woff:"font/woff",otf:"application/x-font-opentype",ttf:"application/x-font-ttf",eot:"application/vnd.ms-fontobject"},r=/(^.+src:\s*)(.+?)(;.*)$/,n=/url\(["']?(.+?)["']?\)(\s*format\(.+?\))?/g,i=new RegExp("url\\([\"\\']?(.+?\\.("+Object.keys(e).join("|")+")(\\?.*?)?)[\"\\']?\\)");function o(o){var a=o.cssText.match(r);if(a){var s=a[1],u=a[2],c=a[3],f=u.match(n);if(Array.isArray(f))return f.map((function(t){return function(t,e){var r=t.match(i),n=r&&r[1]||"";if(n&&!n.match(/^data:/)&&"about:blank"!==n)return n.startsWith("../")?n=e+"/../"+n:n.startsWith("./")&&(n=e+"/."+n),{fmt:r[2],url:n,css:t}}(t,o.href)})).filter((function(t){return!!t})).map((function(e){return e.order=t.indexOf(e.fmt),e})).sort((function(t,e){return t.order-e.order})).slice(0,1).map((function(t){return{text:s+t.css+c,format:e[t.fmt],url:t.url}})).pop()}}return Array.from(document.styleSheets).map((function(t){try{return{cssRules:t.cssRules,href:t.href}}catch(e){console.warn("Stylesheet could not be loaded: "+t.href,e)}})).map((function(t){return t&&t.cssRules?Array.from(t.cssRules).filter((function(t){return t.cssText.match(/^@font-face/)})).map((function(e){return{href:t.href,cssText:e.cssText}})):[]})).flat().map((function(t){return o(t)})).filter((function(t){return!!t}))}()),saveSvgAsPng(document.getElementById(this.svgid),this.pngname,{encoderOptions:1,fonts:this.fonts})}}])&&yt(t.prototype,e),Object.defineProperty(t,"prototype",{writable:!1}),t;var t,e}();function gt(t){return gt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},gt(t)}function mt(t,e){for(var r=0;r0?"hover_inv":null,r.classPrefix="hover_key",r.attrName="key-id",r.shinyInputSuffix="_key_hovered",r.shinyMessageSuffix="_key_hovered_set",n.classPrefix="hover_theme",n.attrName="theme-id",n.shinyInputSuffix="_theme_hovered",n.shinyMessageSuffix="_theme_hovered_set";var i,o=[t,r,n];try{o.forEach((function(t){t.shinyInputId=this.shinyMode&&t.reactive?this.containerid+t.shinyInputSuffix:null,t.shinyMessageId=this.shinyMode&&t.reactive?this.containerid+t.shinyMessageSuffix:null,(i=new J(this.svgid,t)).init()&&this.handlers.set(t.classPrefix,i)}),this)}catch(t){console.error(t)}try{(i=new ht(this.svgid,[t.attrName],t.nearest_distance)).init()&&this.handlers.set("nearest",i)}catch(t){console.error(t)}}},{key:"setupSelection",value:function(t,e,r,n){t.classPrefix="select_data",t.attrName="data-id",t.shinyInputSuffix="_selected",t.shinyMessageSuffix="_set",t.invClassPrefix=e.css.length>0?"select_inv":null,r.classPrefix="select_key",r.attrName="key-id",r.shinyInputSuffix="_key_selected",r.shinyMessageSuffix="_key_set",n.classPrefix="select_theme",n.attrName="theme-id",n.shinyInputSuffix="_theme_selected",n.shinyMessageSuffix="_theme_set";var i,o=[t,r,n];try{o.forEach((function(t){!this.shinyMode&&t.only_shiny||(t.shinyInputId=this.shinyMode?this.containerid+t.shinyInputSuffix:null,t.shinyMessageId=this.shinyMode?this.containerid+t.shinyMessageSuffix:null,(i=new et(this.svgid,t)).init()&&this.handlers.set(t.classPrefix,i))}),this)}catch(t){console.error(t)}}},{key:"setupMouse",value:function(){try{var t=new Map;ot.forEach((function(e){return t.set(e,[])})),this.handlers.forEach((function(e){e instanceof $?(t.get("mouseover").push(e),t.get("mouseout").push(e),t.get("mousemove").push(e),t.get("mousedown").push(e),t.get("wheel").push(e),t.get("nearest").push(e)):e instanceof J?(t.get("mouseover").push(e),t.get("mouseout").push(e),t.get("nearest").push(e)):e instanceof et?t.get("click").push(e):e instanceof s&&(t.get("mouseover").push(e),t.get("mouseout").push(e))}));var e=new at(this.svgid,t,this.handlers.get("nearest"));e.init()&&this.handlers.set("mouse",e)}catch(t){console.error(t)}}},{key:"setupZoom",value:function(t){try{var e=new l(this.svgid,t);e.init()&&this.handlers.set("zoom",e)}catch(t){console.error(t)}}},{key:"setupToolbar",value:function(t){var e;try{t.hidden.includes("saveaspng")||(e=new dt(this.svgid,{pngname:t.pngname})).init()&&this.handlers.set("png",e)}catch(t){console.error(t)}try{var r=[];this.handlers.forEach((function(t){(t instanceof dt||t instanceof l||t instanceof et&&"data-id"==t.attrName&&"multiple"==t.type)&&r.push(t)})),t.clsName="ggiraph-toolbar",(e=new s(this.containerid,this.svgid,t)).init(r)&&this.handlers.set("toolbar",e)}catch(t){console.error(t)}}}])&&mt(r.prototype,n),Object.defineProperty(r,"prototype",{writable:!1}),r;var r,n}();function wt(t){return function(e,r,n){var i=new bt(e.id,t);return{renderValue:function(r){i.clear(),i.setSvgId(r.uid),i.addStyle([r.settings.tooltip.css,r.settings.select_inv.css,r.settings.select.css,r.settings.select_key.css,r.settings.select_theme.css,r.settings.hover_inv.css,r.settings.hover.css,r.settings.hover_key.css,r.settings.hover_theme.css]),i.addSvg(r.html,r.js);var n=d3.select("#"+i.svgid).property("viewBox").baseVal;r.settings.sizing.rescale?t?(i.autoScale("100%"),i.IEFixResize(1,1/r.ratio),i.setSizeLimits(d3.select(e).style("width"),0,d3.select(e).style("height"),0)):(i.autoScale(Math.round(100*r.settings.sizing.width)+"%"),i.IEFixResize(r.settings.sizing.width,1/r.ratio),i.setSizeLimits("unset","unset","unset","unset"),i.removeContainerLimits()):(i.fixSize(n.width,n.height),d3.select(e).style("width",null).style("height",null)),i.setupHover(r.settings.hover,r.settings.hover_inv,r.settings.hover_key,r.settings.hover_theme),i.setupSelection(r.settings.select,r.settings.select_inv,r.settings.select_key,r.settings.select_theme),i.setupZoom(r.settings.zoom),i.setupToolbar(r.settings.toolbar),i.setupTooltip(r.settings.tooltip),i.setupMouse()},resize:function(t,e){}}}}})(),o})())); \ No newline at end of file diff --git a/content/blog/ggplot2-styling/girafe-binding-0.9.1/girafe.js b/content/blog/ggplot2-styling/girafe-binding-0.9.1/girafe.js new file mode 100644 index 000000000..1c6a1ce56 --- /dev/null +++ b/content/blog/ggplot2-styling/girafe-binding-0.9.1/girafe.js @@ -0,0 +1,5 @@ +HTMLWidgets.widget({ + name: 'girafe', + type: 'output', + factory: ggiraphjs.factory(HTMLWidgets.shinyMode) +}); diff --git a/content/blog/ggplot2-styling/htmltools-fill-0.5.8.1/fill.css b/content/blog/ggplot2-styling/htmltools-fill-0.5.8.1/fill.css new file mode 100644 index 000000000..841ea9d59 --- /dev/null +++ b/content/blog/ggplot2-styling/htmltools-fill-0.5.8.1/fill.css @@ -0,0 +1,21 @@ +@layer htmltools { + .html-fill-container { + display: flex; + flex-direction: column; + /* Prevent the container from expanding vertically or horizontally beyond its + parent's constraints. */ + min-height: 0; + min-width: 0; + } + .html-fill-container > .html-fill-item { + /* Fill items can grow and shrink freely within + available vertical space in fillable container */ + flex: 1 1 auto; + min-height: 0; + min-width: 0; + } + .html-fill-container > :not(.html-fill-item) { + /* Prevent shrinking or growing of non-fill items */ + flex: 0 0 auto; + } +} diff --git a/content/blog/ggplot2-styling/htmlwidgets-1.6.4/htmlwidgets.js b/content/blog/ggplot2-styling/htmlwidgets-1.6.4/htmlwidgets.js new file mode 100644 index 000000000..1067d029f --- /dev/null +++ b/content/blog/ggplot2-styling/htmlwidgets-1.6.4/htmlwidgets.js @@ -0,0 +1,901 @@ +(function() { + // If window.HTMLWidgets is already defined, then use it; otherwise create a + // new object. This allows preceding code to set options that affect the + // initialization process (though none currently exist). + window.HTMLWidgets = window.HTMLWidgets || {}; + + // See if we're running in a viewer pane. If not, we're in a web browser. + var viewerMode = window.HTMLWidgets.viewerMode = + /\bviewer_pane=1\b/.test(window.location); + + // See if we're running in Shiny mode. If not, it's a static document. + // Note that static widgets can appear in both Shiny and static modes, but + // obviously, Shiny widgets can only appear in Shiny apps/documents. + var shinyMode = window.HTMLWidgets.shinyMode = + typeof(window.Shiny) !== "undefined" && !!window.Shiny.outputBindings; + + // We can't count on jQuery being available, so we implement our own + // version if necessary. + function querySelectorAll(scope, selector) { + if (typeof(jQuery) !== "undefined" && scope instanceof jQuery) { + return scope.find(selector); + } + if (scope.querySelectorAll) { + return scope.querySelectorAll(selector); + } + } + + function asArray(value) { + if (value === null) + return []; + if ($.isArray(value)) + return value; + return [value]; + } + + // Implement jQuery's extend + function extend(target /*, ... */) { + if (arguments.length == 1) { + return target; + } + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var prop in source) { + if (source.hasOwnProperty(prop)) { + target[prop] = source[prop]; + } + } + } + return target; + } + + // IE8 doesn't support Array.forEach. + function forEach(values, callback, thisArg) { + if (values.forEach) { + values.forEach(callback, thisArg); + } else { + for (var i = 0; i < values.length; i++) { + callback.call(thisArg, values[i], i, values); + } + } + } + + // Replaces the specified method with the return value of funcSource. + // + // Note that funcSource should not BE the new method, it should be a function + // that RETURNS the new method. funcSource receives a single argument that is + // the overridden method, it can be called from the new method. The overridden + // method can be called like a regular function, it has the target permanently + // bound to it so "this" will work correctly. + function overrideMethod(target, methodName, funcSource) { + var superFunc = target[methodName] || function() {}; + var superFuncBound = function() { + return superFunc.apply(target, arguments); + }; + target[methodName] = funcSource(superFuncBound); + } + + // Add a method to delegator that, when invoked, calls + // delegatee.methodName. If there is no such method on + // the delegatee, but there was one on delegator before + // delegateMethod was called, then the original version + // is invoked instead. + // For example: + // + // var a = { + // method1: function() { console.log('a1'); } + // method2: function() { console.log('a2'); } + // }; + // var b = { + // method1: function() { console.log('b1'); } + // }; + // delegateMethod(a, b, "method1"); + // delegateMethod(a, b, "method2"); + // a.method1(); + // a.method2(); + // + // The output would be "b1", "a2". + function delegateMethod(delegator, delegatee, methodName) { + var inherited = delegator[methodName]; + delegator[methodName] = function() { + var target = delegatee; + var method = delegatee[methodName]; + + // The method doesn't exist on the delegatee. Instead, + // call the method on the delegator, if it exists. + if (!method) { + target = delegator; + method = inherited; + } + + if (method) { + return method.apply(target, arguments); + } + }; + } + + // Implement a vague facsimilie of jQuery's data method + function elementData(el, name, value) { + if (arguments.length == 2) { + return el["htmlwidget_data_" + name]; + } else if (arguments.length == 3) { + el["htmlwidget_data_" + name] = value; + return el; + } else { + throw new Error("Wrong number of arguments for elementData: " + + arguments.length); + } + } + + // http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex + function escapeRegExp(str) { + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); + } + + function hasClass(el, className) { + var re = new RegExp("\\b" + escapeRegExp(className) + "\\b"); + return re.test(el.className); + } + + // elements - array (or array-like object) of HTML elements + // className - class name to test for + // include - if true, only return elements with given className; + // if false, only return elements *without* given className + function filterByClass(elements, className, include) { + var results = []; + for (var i = 0; i < elements.length; i++) { + if (hasClass(elements[i], className) == include) + results.push(elements[i]); + } + return results; + } + + function on(obj, eventName, func) { + if (obj.addEventListener) { + obj.addEventListener(eventName, func, false); + } else if (obj.attachEvent) { + obj.attachEvent(eventName, func); + } + } + + function off(obj, eventName, func) { + if (obj.removeEventListener) + obj.removeEventListener(eventName, func, false); + else if (obj.detachEvent) { + obj.detachEvent(eventName, func); + } + } + + // Translate array of values to top/right/bottom/left, as usual with + // the "padding" CSS property + // https://developer.mozilla.org/en-US/docs/Web/CSS/padding + function unpackPadding(value) { + if (typeof(value) === "number") + value = [value]; + if (value.length === 1) { + return {top: value[0], right: value[0], bottom: value[0], left: value[0]}; + } + if (value.length === 2) { + return {top: value[0], right: value[1], bottom: value[0], left: value[1]}; + } + if (value.length === 3) { + return {top: value[0], right: value[1], bottom: value[2], left: value[1]}; + } + if (value.length === 4) { + return {top: value[0], right: value[1], bottom: value[2], left: value[3]}; + } + } + + // Convert an unpacked padding object to a CSS value + function paddingToCss(paddingObj) { + return paddingObj.top + "px " + paddingObj.right + "px " + paddingObj.bottom + "px " + paddingObj.left + "px"; + } + + // Makes a number suitable for CSS + function px(x) { + if (typeof(x) === "number") + return x + "px"; + else + return x; + } + + // Retrieves runtime widget sizing information for an element. + // The return value is either null, or an object with fill, padding, + // defaultWidth, defaultHeight fields. + function sizingPolicy(el) { + var sizingEl = document.querySelector("script[data-for='" + el.id + "'][type='application/htmlwidget-sizing']"); + if (!sizingEl) + return null; + var sp = JSON.parse(sizingEl.textContent || sizingEl.text || "{}"); + if (viewerMode) { + return sp.viewer; + } else { + return sp.browser; + } + } + + // @param tasks Array of strings (or falsy value, in which case no-op). + // Each element must be a valid JavaScript expression that yields a + // function. Or, can be an array of objects with "code" and "data" + // properties; in this case, the "code" property should be a string + // of JS that's an expr that yields a function, and "data" should be + // an object that will be added as an additional argument when that + // function is called. + // @param target The object that will be "this" for each function + // execution. + // @param args Array of arguments to be passed to the functions. (The + // same arguments will be passed to all functions.) + function evalAndRun(tasks, target, args) { + if (tasks) { + forEach(tasks, function(task) { + var theseArgs = args; + if (typeof(task) === "object") { + theseArgs = theseArgs.concat([task.data]); + task = task.code; + } + var taskFunc = tryEval(task); + if (typeof(taskFunc) !== "function") { + throw new Error("Task must be a function! Source:\n" + task); + } + taskFunc.apply(target, theseArgs); + }); + } + } + + // Attempt eval() both with and without enclosing in parentheses. + // Note that enclosing coerces a function declaration into + // an expression that eval() can parse + // (otherwise, a SyntaxError is thrown) + function tryEval(code) { + var result = null; + try { + result = eval("(" + code + ")"); + } catch(error) { + if (!(error instanceof SyntaxError)) { + throw error; + } + try { + result = eval(code); + } catch(e) { + if (e instanceof SyntaxError) { + throw error; + } else { + throw e; + } + } + } + return result; + } + + function initSizing(el) { + var sizing = sizingPolicy(el); + if (!sizing) + return; + + var cel = document.getElementById("htmlwidget_container"); + if (!cel) + return; + + if (typeof(sizing.padding) !== "undefined") { + document.body.style.margin = "0"; + document.body.style.padding = paddingToCss(unpackPadding(sizing.padding)); + } + + if (sizing.fill) { + document.body.style.overflow = "hidden"; + document.body.style.width = "100%"; + document.body.style.height = "100%"; + document.documentElement.style.width = "100%"; + document.documentElement.style.height = "100%"; + cel.style.position = "absolute"; + var pad = unpackPadding(sizing.padding); + cel.style.top = pad.top + "px"; + cel.style.right = pad.right + "px"; + cel.style.bottom = pad.bottom + "px"; + cel.style.left = pad.left + "px"; + el.style.width = "100%"; + el.style.height = "100%"; + + return { + getWidth: function() { return cel.getBoundingClientRect().width; }, + getHeight: function() { return cel.getBoundingClientRect().height; } + }; + + } else { + el.style.width = px(sizing.width); + el.style.height = px(sizing.height); + + return { + getWidth: function() { return cel.getBoundingClientRect().width; }, + getHeight: function() { return cel.getBoundingClientRect().height; } + }; + } + } + + // Default implementations for methods + var defaults = { + find: function(scope) { + return querySelectorAll(scope, "." + this.name); + }, + renderError: function(el, err) { + var $el = $(el); + + this.clearError(el); + + // Add all these error classes, as Shiny does + var errClass = "shiny-output-error"; + if (err.type !== null) { + // use the classes of the error condition as CSS class names + errClass = errClass + " " + $.map(asArray(err.type), function(type) { + return errClass + "-" + type; + }).join(" "); + } + errClass = errClass + " htmlwidgets-error"; + + // Is el inline or block? If inline or inline-block, just display:none it + // and add an inline error. + var display = $el.css("display"); + $el.data("restore-display-mode", display); + + if (display === "inline" || display === "inline-block") { + $el.hide(); + if (err.message !== "") { + var errorSpan = $("").addClass(errClass); + errorSpan.text(err.message); + $el.after(errorSpan); + } + } else if (display === "block") { + // If block, add an error just after the el, set visibility:none on the + // el, and position the error to be on top of the el. + // Mark it with a unique ID and CSS class so we can remove it later. + $el.css("visibility", "hidden"); + if (err.message !== "") { + var errorDiv = $("
").addClass(errClass).css("position", "absolute") + .css("top", el.offsetTop) + .css("left", el.offsetLeft) + // setting width can push out the page size, forcing otherwise + // unnecessary scrollbars to appear and making it impossible for + // the element to shrink; so use max-width instead + .css("maxWidth", el.offsetWidth) + .css("height", el.offsetHeight); + errorDiv.text(err.message); + $el.after(errorDiv); + + // Really dumb way to keep the size/position of the error in sync with + // the parent element as the window is resized or whatever. + var intId = setInterval(function() { + if (!errorDiv[0].parentElement) { + clearInterval(intId); + return; + } + errorDiv + .css("top", el.offsetTop) + .css("left", el.offsetLeft) + .css("maxWidth", el.offsetWidth) + .css("height", el.offsetHeight); + }, 500); + } + } + }, + clearError: function(el) { + var $el = $(el); + var display = $el.data("restore-display-mode"); + $el.data("restore-display-mode", null); + + if (display === "inline" || display === "inline-block") { + if (display) + $el.css("display", display); + $(el.nextSibling).filter(".htmlwidgets-error").remove(); + } else if (display === "block"){ + $el.css("visibility", "inherit"); + $(el.nextSibling).filter(".htmlwidgets-error").remove(); + } + }, + sizing: {} + }; + + // Called by widget bindings to register a new type of widget. The definition + // object can contain the following properties: + // - name (required) - A string indicating the binding name, which will be + // used by default as the CSS classname to look for. + // - initialize (optional) - A function(el) that will be called once per + // widget element; if a value is returned, it will be passed as the third + // value to renderValue. + // - renderValue (required) - A function(el, data, initValue) that will be + // called with data. Static contexts will cause this to be called once per + // element; Shiny apps will cause this to be called multiple times per + // element, as the data changes. + window.HTMLWidgets.widget = function(definition) { + if (!definition.name) { + throw new Error("Widget must have a name"); + } + if (!definition.type) { + throw new Error("Widget must have a type"); + } + // Currently we only support output widgets + if (definition.type !== "output") { + throw new Error("Unrecognized widget type '" + definition.type + "'"); + } + // TODO: Verify that .name is a valid CSS classname + + // Support new-style instance-bound definitions. Old-style class-bound + // definitions have one widget "object" per widget per type/class of + // widget; the renderValue and resize methods on such widget objects + // take el and instance arguments, because the widget object can't + // store them. New-style instance-bound definitions have one widget + // object per widget instance; the definition that's passed in doesn't + // provide renderValue or resize methods at all, just the single method + // factory(el, width, height) + // which returns an object that has renderValue(x) and resize(w, h). + // This enables a far more natural programming style for the widget + // author, who can store per-instance state using either OO-style + // instance fields or functional-style closure variables (I guess this + // is in contrast to what can only be called C-style pseudo-OO which is + // what we required before). + if (definition.factory) { + definition = createLegacyDefinitionAdapter(definition); + } + + if (!definition.renderValue) { + throw new Error("Widget must have a renderValue function"); + } + + // For static rendering (non-Shiny), use a simple widget registration + // scheme. We also use this scheme for Shiny apps/documents that also + // contain static widgets. + window.HTMLWidgets.widgets = window.HTMLWidgets.widgets || []; + // Merge defaults into the definition; don't mutate the original definition. + var staticBinding = extend({}, defaults, definition); + overrideMethod(staticBinding, "find", function(superfunc) { + return function(scope) { + var results = superfunc(scope); + // Filter out Shiny outputs, we only want the static kind + return filterByClass(results, "html-widget-output", false); + }; + }); + window.HTMLWidgets.widgets.push(staticBinding); + + if (shinyMode) { + // Shiny is running. Register the definition with an output binding. + // The definition itself will not be the output binding, instead + // we will make an output binding object that delegates to the + // definition. This is because we foolishly used the same method + // name (renderValue) for htmlwidgets definition and Shiny bindings + // but they actually have quite different semantics (the Shiny + // bindings receive data that includes lots of metadata that it + // strips off before calling htmlwidgets renderValue). We can't + // just ignore the difference because in some widgets it's helpful + // to call this.renderValue() from inside of resize(), and if + // we're not delegating, then that call will go to the Shiny + // version instead of the htmlwidgets version. + + // Merge defaults with definition, without mutating either. + var bindingDef = extend({}, defaults, definition); + + // This object will be our actual Shiny binding. + var shinyBinding = new Shiny.OutputBinding(); + + // With a few exceptions, we'll want to simply use the bindingDef's + // version of methods if they are available, otherwise fall back to + // Shiny's defaults. NOTE: If Shiny's output bindings gain additional + // methods in the future, and we want them to be overrideable by + // HTMLWidget binding definitions, then we'll need to add them to this + // list. + delegateMethod(shinyBinding, bindingDef, "getId"); + delegateMethod(shinyBinding, bindingDef, "onValueChange"); + delegateMethod(shinyBinding, bindingDef, "onValueError"); + delegateMethod(shinyBinding, bindingDef, "renderError"); + delegateMethod(shinyBinding, bindingDef, "clearError"); + delegateMethod(shinyBinding, bindingDef, "showProgress"); + + // The find, renderValue, and resize are handled differently, because we + // want to actually decorate the behavior of the bindingDef methods. + + shinyBinding.find = function(scope) { + var results = bindingDef.find(scope); + + // Only return elements that are Shiny outputs, not static ones + var dynamicResults = results.filter(".html-widget-output"); + + // It's possible that whatever caused Shiny to think there might be + // new dynamic outputs, also caused there to be new static outputs. + // Since there might be lots of different htmlwidgets bindings, we + // schedule execution for later--no need to staticRender multiple + // times. + if (results.length !== dynamicResults.length) + scheduleStaticRender(); + + return dynamicResults; + }; + + // Wrap renderValue to handle initialization, which unfortunately isn't + // supported natively by Shiny at the time of this writing. + + shinyBinding.renderValue = function(el, data) { + Shiny.renderDependencies(data.deps); + // Resolve strings marked as javascript literals to objects + if (!(data.evals instanceof Array)) data.evals = [data.evals]; + for (var i = 0; data.evals && i < data.evals.length; i++) { + window.HTMLWidgets.evaluateStringMember(data.x, data.evals[i]); + } + if (!bindingDef.renderOnNullValue) { + if (data.x === null) { + el.style.visibility = "hidden"; + return; + } else { + el.style.visibility = "inherit"; + } + } + if (!elementData(el, "initialized")) { + initSizing(el); + + elementData(el, "initialized", true); + if (bindingDef.initialize) { + var rect = el.getBoundingClientRect(); + var result = bindingDef.initialize(el, rect.width, rect.height); + elementData(el, "init_result", result); + } + } + bindingDef.renderValue(el, data.x, elementData(el, "init_result")); + evalAndRun(data.jsHooks.render, elementData(el, "init_result"), [el, data.x]); + }; + + // Only override resize if bindingDef implements it + if (bindingDef.resize) { + shinyBinding.resize = function(el, width, height) { + // Shiny can call resize before initialize/renderValue have been + // called, which doesn't make sense for widgets. + if (elementData(el, "initialized")) { + bindingDef.resize(el, width, height, elementData(el, "init_result")); + } + }; + } + + Shiny.outputBindings.register(shinyBinding, bindingDef.name); + } + }; + + var scheduleStaticRenderTimerId = null; + function scheduleStaticRender() { + if (!scheduleStaticRenderTimerId) { + scheduleStaticRenderTimerId = setTimeout(function() { + scheduleStaticRenderTimerId = null; + window.HTMLWidgets.staticRender(); + }, 1); + } + } + + // Render static widgets after the document finishes loading + // Statically render all elements that are of this widget's class + window.HTMLWidgets.staticRender = function() { + var bindings = window.HTMLWidgets.widgets || []; + forEach(bindings, function(binding) { + var matches = binding.find(document.documentElement); + forEach(matches, function(el) { + var sizeObj = initSizing(el, binding); + + var getSize = function(el) { + if (sizeObj) { + return {w: sizeObj.getWidth(), h: sizeObj.getHeight()} + } else { + var rect = el.getBoundingClientRect(); + return {w: rect.width, h: rect.height} + } + }; + + if (hasClass(el, "html-widget-static-bound")) + return; + el.className = el.className + " html-widget-static-bound"; + + var initResult; + if (binding.initialize) { + var size = getSize(el); + initResult = binding.initialize(el, size.w, size.h); + elementData(el, "init_result", initResult); + } + + if (binding.resize) { + var lastSize = getSize(el); + var resizeHandler = function(e) { + var size = getSize(el); + if (size.w === 0 && size.h === 0) + return; + if (size.w === lastSize.w && size.h === lastSize.h) + return; + lastSize = size; + binding.resize(el, size.w, size.h, initResult); + }; + + on(window, "resize", resizeHandler); + + // This is needed for cases where we're running in a Shiny + // app, but the widget itself is not a Shiny output, but + // rather a simple static widget. One example of this is + // an rmarkdown document that has runtime:shiny and widget + // that isn't in a render function. Shiny only knows to + // call resize handlers for Shiny outputs, not for static + // widgets, so we do it ourselves. + if (window.jQuery) { + window.jQuery(document).on( + "shown.htmlwidgets shown.bs.tab.htmlwidgets shown.bs.collapse.htmlwidgets", + resizeHandler + ); + window.jQuery(document).on( + "hidden.htmlwidgets hidden.bs.tab.htmlwidgets hidden.bs.collapse.htmlwidgets", + resizeHandler + ); + } + + // This is needed for the specific case of ioslides, which + // flips slides between display:none and display:block. + // Ideally we would not have to have ioslide-specific code + // here, but rather have ioslides raise a generic event, + // but the rmarkdown package just went to CRAN so the + // window to getting that fixed may be long. + if (window.addEventListener) { + // It's OK to limit this to window.addEventListener + // browsers because ioslides itself only supports + // such browsers. + on(document, "slideenter", resizeHandler); + on(document, "slideleave", resizeHandler); + } + } + + var scriptData = document.querySelector("script[data-for='" + el.id + "'][type='application/json']"); + if (scriptData) { + var data = JSON.parse(scriptData.textContent || scriptData.text); + // Resolve strings marked as javascript literals to objects + if (!(data.evals instanceof Array)) data.evals = [data.evals]; + for (var k = 0; data.evals && k < data.evals.length; k++) { + window.HTMLWidgets.evaluateStringMember(data.x, data.evals[k]); + } + binding.renderValue(el, data.x, initResult); + evalAndRun(data.jsHooks.render, initResult, [el, data.x]); + } + }); + }); + + invokePostRenderHandlers(); + } + + + function has_jQuery3() { + if (!window.jQuery) { + return false; + } + var $version = window.jQuery.fn.jquery; + var $major_version = parseInt($version.split(".")[0]); + return $major_version >= 3; + } + + /* + / Shiny 1.4 bumped jQuery from 1.x to 3.x which means jQuery's + / on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now + / really means $(setTimeout(fn)). + / https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous + / + / Since Shiny uses $() to schedule initShiny, shiny>=1.4 calls initShiny + / one tick later than it did before, which means staticRender() is + / called renderValue() earlier than (advanced) widget authors might be expecting. + / https://github.com/rstudio/shiny/issues/2630 + / + / For a concrete example, leaflet has some methods (e.g., updateBounds) + / which reference Shiny methods registered in initShiny (e.g., setInputValue). + / Since leaflet is privy to this life-cycle, it knows to use setTimeout() to + / delay execution of those methods (until Shiny methods are ready) + / https://github.com/rstudio/leaflet/blob/18ec981/javascript/src/index.js#L266-L268 + / + / Ideally widget authors wouldn't need to use this setTimeout() hack that + / leaflet uses to call Shiny methods on a staticRender(). In the long run, + / the logic initShiny should be broken up so that method registration happens + / right away, but binding happens later. + */ + function maybeStaticRenderLater() { + if (shinyMode && has_jQuery3()) { + window.jQuery(window.HTMLWidgets.staticRender); + } else { + window.HTMLWidgets.staticRender(); + } + } + + if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", function() { + document.removeEventListener("DOMContentLoaded", arguments.callee, false); + maybeStaticRenderLater(); + }, false); + } else if (document.attachEvent) { + document.attachEvent("onreadystatechange", function() { + if (document.readyState === "complete") { + document.detachEvent("onreadystatechange", arguments.callee); + maybeStaticRenderLater(); + } + }); + } + + + window.HTMLWidgets.getAttachmentUrl = function(depname, key) { + // If no key, default to the first item + if (typeof(key) === "undefined") + key = 1; + + var link = document.getElementById(depname + "-" + key + "-attachment"); + if (!link) { + throw new Error("Attachment " + depname + "/" + key + " not found in document"); + } + return link.getAttribute("href"); + }; + + window.HTMLWidgets.dataframeToD3 = function(df) { + var names = []; + var length; + for (var name in df) { + if (df.hasOwnProperty(name)) + names.push(name); + if (typeof(df[name]) !== "object" || typeof(df[name].length) === "undefined") { + throw new Error("All fields must be arrays"); + } else if (typeof(length) !== "undefined" && length !== df[name].length) { + throw new Error("All fields must be arrays of the same length"); + } + length = df[name].length; + } + var results = []; + var item; + for (var row = 0; row < length; row++) { + item = {}; + for (var col = 0; col < names.length; col++) { + item[names[col]] = df[names[col]][row]; + } + results.push(item); + } + return results; + }; + + window.HTMLWidgets.transposeArray2D = function(array) { + if (array.length === 0) return array; + var newArray = array[0].map(function(col, i) { + return array.map(function(row) { + return row[i] + }) + }); + return newArray; + }; + // Split value at splitChar, but allow splitChar to be escaped + // using escapeChar. Any other characters escaped by escapeChar + // will be included as usual (including escapeChar itself). + function splitWithEscape(value, splitChar, escapeChar) { + var results = []; + var escapeMode = false; + var currentResult = ""; + for (var pos = 0; pos < value.length; pos++) { + if (!escapeMode) { + if (value[pos] === splitChar) { + results.push(currentResult); + currentResult = ""; + } else if (value[pos] === escapeChar) { + escapeMode = true; + } else { + currentResult += value[pos]; + } + } else { + currentResult += value[pos]; + escapeMode = false; + } + } + if (currentResult !== "") { + results.push(currentResult); + } + return results; + } + // Function authored by Yihui/JJ Allaire + window.HTMLWidgets.evaluateStringMember = function(o, member) { + var parts = splitWithEscape(member, '.', '\\'); + for (var i = 0, l = parts.length; i < l; i++) { + var part = parts[i]; + // part may be a character or 'numeric' member name + if (o !== null && typeof o === "object" && part in o) { + if (i == (l - 1)) { // if we are at the end of the line then evalulate + if (typeof o[part] === "string") + o[part] = tryEval(o[part]); + } else { // otherwise continue to next embedded object + o = o[part]; + } + } + } + }; + + // Retrieve the HTMLWidget instance (i.e. the return value of an + // HTMLWidget binding's initialize() or factory() function) + // associated with an element, or null if none. + window.HTMLWidgets.getInstance = function(el) { + return elementData(el, "init_result"); + }; + + // Finds the first element in the scope that matches the selector, + // and returns the HTMLWidget instance (i.e. the return value of + // an HTMLWidget binding's initialize() or factory() function) + // associated with that element, if any. If no element matches the + // selector, or the first matching element has no HTMLWidget + // instance associated with it, then null is returned. + // + // The scope argument is optional, and defaults to window.document. + window.HTMLWidgets.find = function(scope, selector) { + if (arguments.length == 1) { + selector = scope; + scope = document; + } + + var el = scope.querySelector(selector); + if (el === null) { + return null; + } else { + return window.HTMLWidgets.getInstance(el); + } + }; + + // Finds all elements in the scope that match the selector, and + // returns the HTMLWidget instances (i.e. the return values of + // an HTMLWidget binding's initialize() or factory() function) + // associated with the elements, in an array. If elements that + // match the selector don't have an associated HTMLWidget + // instance, the returned array will contain nulls. + // + // The scope argument is optional, and defaults to window.document. + window.HTMLWidgets.findAll = function(scope, selector) { + if (arguments.length == 1) { + selector = scope; + scope = document; + } + + var nodes = scope.querySelectorAll(selector); + var results = []; + for (var i = 0; i < nodes.length; i++) { + results.push(window.HTMLWidgets.getInstance(nodes[i])); + } + return results; + }; + + var postRenderHandlers = []; + function invokePostRenderHandlers() { + while (postRenderHandlers.length) { + var handler = postRenderHandlers.shift(); + if (handler) { + handler(); + } + } + } + + // Register the given callback function to be invoked after the + // next time static widgets are rendered. + window.HTMLWidgets.addPostRenderHandler = function(callback) { + postRenderHandlers.push(callback); + }; + + // Takes a new-style instance-bound definition, and returns an + // old-style class-bound definition. This saves us from having + // to rewrite all the logic in this file to accomodate both + // types of definitions. + function createLegacyDefinitionAdapter(defn) { + var result = { + name: defn.name, + type: defn.type, + initialize: function(el, width, height) { + return defn.factory(el, width, height); + }, + renderValue: function(el, x, instance) { + return instance.renderValue(x); + }, + resize: function(el, width, height, instance) { + return instance.resize(width, height); + } + }; + + if (defn.find) + result.find = defn.find; + if (defn.renderError) + result.renderError = defn.renderError; + if (defn.clearError) + result.clearError = defn.clearError; + + return result; + } +})(); diff --git a/content/blog/ggplot2-styling/index.Rmd b/content/blog/ggplot2-styling/index.Rmd new file mode 100644 index 000000000..f81fede32 --- /dev/null +++ b/content/blog/ggplot2-styling/index.Rmd @@ -0,0 +1,1248 @@ +--- +output: hugodown::md_document + +slug: ggplot2-styling +title: ggplot2 styling +date: 2025-10-01 +author: Teun van den Brand +description: > + This post discusses one function in ggplot2: `theme()`. Find out about the glamour of graphics in this deep-dive article. + +photo: + url: https://www.pexels.com/photo/people-dressed-in-elaborate-costumes-for-venetian-masqueade-5932619 + author: Helena Jankovičová Kováčová + +# one of: "deep-dive", "learn", "package", "programming", "roundup", or "other" +categories: [package] +tags: [] +--- + + + +## So you want to style your plot? + +Diligently, you have read, cleaned and modelled your data. +You have carefully crafted a plot that lets your data speak its story. +Now it is time to polish. +Now it is time to let your visualisation shine. + +We will set out to illuminate how to set the stylistic finishing touches on your visualisations made with the ggplot2 package. +The ggplot2 package has had a [recent release](https://www.tidyverse.org/blog/2025/09/ggplot2-4-0-0/) that included some relevant changes to styling plots. +In ggplot2, the theme system is responsible for many non-data aspects of how your plot looks. +It covers anything from panels, to axes, titles and legends. +Here, we'll get started with digesting important parts of the theme system. +We'll start with complete themes, get into theme elements followed by how these elements are used in various parts of the plot and finish off with some tips, including how to write your own theme functions. +Before we begin discussing themes, let's make an example plot that can showcase many aspects. + +```{r, echo=FALSE} +knitr::opts_chunk$set(dev = "ragg_png") +``` + + +```{r base_plot, fig.keep='none'} +library(ggplot2) + +p <- ggplot(mpg, aes(displ, hwy, colour = cty, shape = drv)) + + geom_point() + + facet_grid(~ year) + + labs( + title = "Fuel efficiency", + subtitle = paste0("Described for ", nrow(mpg), " cars from 1999 and 2008"), + caption = "Source: U.S. Environmental Protection Agency", + x = "Engine Displacement", + y = "Highway miles per gallon", + colour = "City miles\nper gallon", + shape = "Drive train" + ) + +p +``` + +```{r, echo = FALSE} +library(ggiraph) + +text <- function(label) { + element_text_interactive( + tooltip = paste0("", label, ""), + data_id = label, + hover_css = "fill:red;" + ) +} + +line <- function(label, ...) { + element_line_interactive( + tooltip = paste0("", label, ""), + data_id = label, + hover_css = "stroke:red;", + ... + ) +} + +rect <- function(label, fill = "#FF8888", ...) { + element_rect_interactive( + tooltip = paste0("", label, ""), + data_id = label, + hover_css = paste0("stroke:red;fill:", fill, ";"), + ... + ) +} + +interactive_plot <- ggplot(mpg, aes(displ, hwy, colour = cty, shape = drv)) + + geom_point_interactive( + tooltip = "geom", data_id = "geom", + hover_css = ggiraph::girafe_css("stroke:red;fill:red;"), + show.legend = c(colour = TRUE, shape = FALSE) + ) + + geom_point_interactive( + data = mpg[0, ], + tooltip = "geom
palette.shape.discrete
", data_id = "shape", + hover_css = ggiraph::girafe_css("stroke:red;fill:red;"), + show.legend = c(shape = TRUE) + ) + + facet_grid(~ year) + + labs( + title = "Fuel efficiency", + subtitle = paste0("Described for ", nrow(mpg), " cars from 1999 and 2008"), + caption = "Source: U.S. Environmental Protection Agency", + x = "Engine Displacement", + y = "Highway miles per gallon", + colour = "City miles\nper gallon", + shape = "Drive train" + ) + + theme( + plot.title = text("plot.title"), + plot.subtitle = text("plot.subtitle"), + plot.caption = text("plot.caption"), + plot.background = rect("plot.background", "#FFEEEE"), + panel.grid.major.x = line("panel.grid.major.x"), + panel.grid.minor.x = line("panel.grid.minor.x"), + panel.grid.major.y = line("panel.grid.major.y"), + panel.grid.minor.y = line("panel.grid.minor.y"), + panel.background = rect("panel.background
panel.border", "#FFCCCC"), + strip.text.x.top = text("strip.text.x.top"), + strip.background.x = rect("strip.background.x"), + axis.text.y.left = text("axis.text.y.left"), + axis.title.y.left = text("axis.title.y.left"), + axis.text.x.bottom = text("axis.text.x.bottom"), + axis.title.x.bottom = text("axis.title.x.bottom"), + axis.line.x.bottom = line("axis.line.x.bottom", colour = NA, linewidth = 1), + axis.line.y.left = line("axis.line.y.left", colour = NA, linewidth = 1), + axis.ticks.x.bottom = line("axis.ticks.x.bottom"), + axis.ticks.y.left = line("axis.ticks.y.left"), + legend.title = text("legend.title"), + legend.text = text("legend.text"), + legend.ticks = line("legend.ticks", colour = "white", linewidth = 0.5 / .pt), + legend.background = rect("legend.background", "#FFEEEE"), + legend.box.background = rect("legend.box.background", "#FFEEEE", color = NA), + legend.key = rect("legend.key", fill = "#FFCCCC"), + legend.frame = rect("legend.frame
palette.colour.continuous", colour = NA, fill = "#FF888888") + ) + +girafe( + ggobj = interactive_plot, options = list( + opts_tooltip("color:black;background-color:#F9F9F9;padding:0.3em;border-radius:0.3em;border:solid grey;border-width:1px;"), + opts_toolbar(saveaspng = FALSE) +)) +``` + +If you haven't already accidentally triggered it, feel free to hover your mouse over the plot above. +Hovering will tell you what theme element you are pointing at. + +## What is a theme? + +In ggplot, a theme is a list of descriptions for various parts of the plot. +It is where you can set the size of your titles, the colours of your panels, the thickness of your grid lines and placement of your legends. + +Themes are declared using the `theme()` function, which populates these descriptions called 'theme elements'. +Some of these elements have a predefined set of properties and can be set using the element functions, like `element_text()`. +Other theme elements can take simpler values like strings, numbers or units. + +Some pre-arranged collections of elements can be found in complete themes, like the iconic `theme_gray()`. +These are convenient ways to quickly swap out the complete look of a plot. + +## Complete themes + +Let's start big and work our way through the more nitty-gritty aspects of theming plots. +The most thorough way to change the styling of a single plot is to swap out the complete theme. +You can do this simply by adding one of the `theme_*()` functions, like `theme_minimal()`. + +```{r example_complete} +p + theme_minimal() +``` + +### Built-in themes + +The base ggplot2 package already comes with a series of 9 built-in complete themes. +For the sake of completeness about complete themes, they are displayed in the fold-out sections below. +You can peruse them at your leisure to help you pick one you might like. + +

theme_grey() (default) + +```{r complete_grey} +p + theme_grey() +``` + +

+ + +

theme_bw() + +```{r complete_bw} +p + theme_bw() +``` + +

+ + +

theme_linedraw() + +```{r complete_linedraw} +p + theme_linedraw() +``` + +

+ +

theme_light() + +```{r complete_light} +p + theme_light() +``` + +

+ +

theme_dark() + +```{r complete_dark} +p + theme_dark() +``` + +

+ +

theme_minimal() + +```{r complete_minimal} +p + theme_minimal() +``` + +

+ +

theme_classic() + +```{r complete_classic} +p + theme_classic() +``` + +

+ + +

theme_void() + +```{r complete_void} +p + theme_void() +``` + +

+ +

theme_test() + +```{r complete_test} +p + theme_test() +``` + +

+ +### Additional themes + +Some packages come with their own themes that you can add to your plots. +For example the cowplot package has a theme that galvanises you to not use [labels that are too small](https://clauswilke.com/dataviz/small-axis-labels.html), and otherwise has a clean look. + +

cowplot::theme_cowplot() + +```{r complete_cowplot} +p + cowplot::theme_cowplot() +``` + +

+ +The ggthemes package hosts themes that reflect other popular venues of data visualisation, such as the economist or FiveThirtyEight. + +

ggthemes::theme_fivethirtyeight() + +```{r complete_ggthemes} +p + ggthemes::theme_fivethirtyeight() +``` + +

+ +If the moods strikes you for a more playful plot, you can use the tvthemes package to style your plot according to TV shows! + +

tvthemes::theme_simpsons() + +```{r complete_tvthemes} +p + tvthemes::theme_simpsons() +``` + +

+ +Aside from these packages that live on CRAN, there are also non-CRAN packages that come with complete themes. You can visit the [extension gallery](https://exts.ggplot2.tidyverse.org/gallery/) and filter on the 'themes' tag to find more packages. + +### Tweaking complete themes + +The complete themes have arguments that affect multiple components across the plot. +Perhaps the most well known is the `base_size` argument that globally controls the size of theme elements, ranging from the text sizes, to line widths, and ---since recently--- even point sizes. + +```{r complete_base_size} +p + theme_bw(base_size = 8) +``` + +A technique used to distinguish visual hierarchy is 'font pairing', meaning that you combine more than one font to convey visual hierarchy. +In web design, it means displaying your headers different from your body text. +In data visualisation, it can mean displaying your titles distinctly from labels. +The most common pairing, and the default one baked into ggplot2, is to display titles larger than labels in the same typeface. +Another popular choice is to use different weights, like 'bold' and 'plain'. +It is now also easier to use different typefaces by pairing the `header_family` and the `base_family` fonts together. +In the example below, we pair a serif font for headers and a sans-serif font for the rest. + +```{r complete_font_family} +p + theme_bw(base_family = "Roboto", header_family = "Roboto Slab") +``` + +A recent addition to styling with complete themes are colour choices. +The `ink` argument roughly amounts to the colour for all foreground elements, like text, lines and points. +This is complemented by the `paper` argument, which affect background elements like the panels and plot background. +Lastly, there is an `accent` argument which controls the display of a few specific layers, like `geom_smooth()` or `geom_contour()`. +For some aspects of the plot, the `ink` and `paper` arguments are mixed to produce intermediate colours. +As an example, when we use `theme_bw()`, the strip fill colour is a mix between the foreground and background to slightly lift this part from the background. +The `ink` and `paper` arguments can also be used to quickly recolour a plot, or to convert a plot to 'dark mode' by using a light `ink` and dark `paper`. + +```{r complete_ink_paper} +p + + # Turning off these aesthetics to prevent grouping + aes(shape = NULL, colour = NULL) + + geom_smooth(method = "lm", formula = y ~ x) + + theme_bw( + ink = "#BBBBBB", + paper = "#333333", + accent = "red" + ) +``` + +## Theme elements + +Rather than swapping out complete themes in one fell swoop, themes can also be tweaked to various degrees. +In ggplot2, themes are a collection of theme elements, where an element describes a property, or set of properties, for a part of the theme. + +### Element functions + +The documentation in `?theme()` will tell you what type of input each theme element will expect. +Some theme elements just expect scalar values and not collections of properties. +You can simply set these in the theme directly. +For example, we all know that the golden ratio is the best ratio, so we can use it in our plot as follows: + +```{r aspect_ratio} +phi <- (1 + sqrt(5)) / 2 +p + theme(aspect.ratio = phi) +``` + +In the cases where a cohesive set of properties serves as a theme element, ggplot2 has `element_*()` functions. +One of the simpler elements is `element_line()` and we can declare a new set of line properties as follows: + +```{r red_line} +red_line <- element_line(colour = "red", linewidth = 2) +red_line +``` + +These elements can then be given to the `theme()` function to assign these properties to a specific part of the theme, like the `axis.line` in this example. + +```{r red_axis} +p + theme(axis.line = red_line) +``` + +Below is an overview of elements and some common places where they are used: + +```{r element_table, echo=FALSE} +elems <- tibble::tribble( + ~ Element, ~ Description, + "`element_blank()`", "Indicator to skip drawing an element.", + "`element_line()`", "Used for axis lines, grid lines and tick marks.", + "`element_rect()`", "Used for (panel) backgrounds, borders and strips.", + "`element_text()`", "Used for (sub)titles, labels, captions.", + "`element_geom()`", "Used to set default properties of layers.", + "`element_polygon()`", "Not used, but provided for reasons of extension.", + "`element_point()`", "Not used, but provided for reasons of extension." +) +knitr::kable(elems) +``` + +In addition to these elements in ggplot2, extension packages can also define custom elements. +Generally speaking, these elements are variants of the elements listed above and often have slightly different properties and are rendered differently. +For example `marquee::element_marquee()` is a subclass of `element_text()`, but interprets the provided text as markdown. +It applies some formatting like `**` for bold, or allows for custom spans like `{.red ...}`. +Another example is `ggh4x::element_part_rect()` that can draw a subset of rectangle borders. + +```{r element_marquee} +p + + labs(title = "**Fuel** {.red efficiency}") + + theme( + plot.title = marquee::element_marquee(), + strip.background = ggh4x::element_part_rect(colour = "black", side = "b") + ) +``` + +### Hierarchy and inheritance + +Most theme elements are hierarchical. +At the root, they are broadly applicable and change large parts of the plot. +At leaves, they are very specific and allow fine grained control. +Travelling from roots to leaves, properties of theme elements are inherited from parent to child. +Some inheritance is very direct, where leaves directly inherit from roots (for example `legend.text`). +Other times, inheritance is more arduous, like for `axis.minor.ticks.y.left`: it inherits from `axis.ticks.y.left`, which inherits from `axis.ticks.y`, which inherits from `axis.ticks`, which finally inherits from `line`. +Most often, elements only have a single parent, but there are subtle exceptions. + +In the example below we set the root `text` element to red text. This is applied (almost) universally to all text in the plot. +We also set the font of the leaf `legend.text` element. We see that not only has the legend text font changed, but it is red as well because of the root `text` element. + +```{r root_leaves} +p + theme( + # A root element + text = element_text(colour = "red"), + # A leaf element + legend.text = element_text(family = "impact") +) +``` + +However, the keen eye spots that the strip text and axis text are *not* red. +This is because in the line of succession, an ancestor declared a different colour property for the text, which overrules the colour property descending from the root `text` element. +In these specific cases, the deviating ancestors are `axis.text` and `strip.text`. + +When we inspect the contents of a theme element, we may find that the elements are `NULL`. +This is simply an indicator that this element will inherit from its ancestor *in toto*. +Another possibility is that some properties of an element are `NULL`. +A `NULL` property means that the property will be inherited from the parent. +When we truly want to know what properties are taken to display a theme element, we can use the `calc_element()` function to resolve the inheritance and populate all the fields. + +```{r inheritance} +# Will inherit entirely from parent +theme_gray()$axis.ticks.x.bottom + +# The element is incomplete +theme_gray()$axis.ticks + +# Proper way to access the properties of an element +calc_element("axis.ticks.x.bottom", theme_gray()) +``` + +The `?theme` documentation often tells you how the elements inherit and `calc_element()` will resolve it for you. +If, for some reason, you need programmatic access to the inheritance tree, you can use `get_element_tree()`. +Let's say you want to find out exactly which elements have multiple parents. +The resulting object is the internal structure ggplot2 uses to resolve inheritance and has an `inherit` field for every element that discerns its direct parent. + +```{r element_tree} +tree <- get_element_tree() +tree$axis.line.x.bottom$inherit +``` + +## Anatomy of a theme + +```{r reset, echo=FALSE} +reset_theme_settings() +``` + + +The `theme()` function has a lot of arguments and can be a bit overwhelming to parse in one take. +At the time of writing, it has `r length(formals(theme))` arguments and `...` is obfuscating additional options. +Because we like structure rather than chaos, let us try to digest the `theme()` function one bite at a time. +Much of the theme has been divided over parts in the `theme_sub_*()` family of functions. +This family are just simple shortcuts. +For example the `theme_sub_axis(title)` argument, populates the `axis.title` element. + +```{r example_theme_sub} +theme_sub_axis(title = element_blank()) +``` + +If you're redefining a series of related settings, it can be beneficial to use the `theme_sub_*()`. +One benefit is brevity. +For example, if you want to tweak the left y-axis a lot, it can be terser to use `theme_sub_axis_left(title, text, ticks)` rather than `theme(axis.title.y.left, axis.text.y.left, axis.ticks.y.left)`. +The second benefit is that it helps organising your theme, preserving a shred of sanity while hatching your plots. + +### Whole plot + +There are a series of mostly textual theme elements that mostly display outside the plot itself. +Using the `theme_sub_plot()` function, we can omit the `plot` prefix in the settings. +We can us it to control the background, as well as the titles, caption and tag text and their placement. +In the plot below, we're tweaking these settings to show the scope. +Note that the text (except for the tag) is now aligned across the plot as a whole, rather than aligned with the panels. + +```{r sub_plot} +p + + labs(tag = "A") + + theme_sub_plot( + # Adjust the background colour + background = element_rect(fill = "cornsilk"), + + # Align title and subtitle to plot instead of panels + title = element_text(hjust = 0), # default, + subtitle = element_text(colour = "dodgerblue"), + title.position = "plot", + + # Align caption to plot instead of panels + caption = element_text(hjust = 1), # default + caption.position = "plot", + + # Place the tag in the top right of the panels instead of top left of plot + tag.position = "topright", + tag.location = "panel" + ) +``` + +### Panels + +An important aspect of the panels are the grid lines. +The grid lines follow the major and minor breaks of the scale, which is also the major distinction in how they are displayed. +The next distinction is whether the lines are horizontal and mark breaks vertically (`y`) or the lines are vertical and mark breaks horizontally (`x`). + +```{r sub_panel} +p + + theme_sub_panel( + # Extra space between panels + spacing.x = unit(1, "cm"), + + # Tweaking all the grid elements + grid = element_line(colour = "grey80"), + + # Turning off the minor grid elements + grid.minor = element_blank(), + + # Tweak the major x/y lines separately + grid.major.x = element_line(linetype = "dotted"), + grid.major.y = element_line(colour = "white") + ) +``` + +Besides grid lines, also the border and the background are important for the panel styling. +They can be confusing because they are similar, but not identical. +Notably, the panel background is underneath the data (unless `ontop = TRUE`), while the panel border is on top of the panel. +You can see this in the plot below, because the white grid lines are visible over the blue background, but not over the red border. + +```{r sub_panel_border_background} +p + + theme_sub_panel( + background = element_rect(fill = "cornsilk", colour = "blue", linewidth = 6), + border = element_rect(colour = "red", linewidth = 3, fill = "black"), + ) +``` + +Both the background and the border are clipped by the coordinate systems clipping setting, e.g. `coord_cartesian(clip)`. +It should also be noted that any `fill` property set on the border is ignored. +Moreover, the legend key background takes on the appearance of the panel background by default, which is why the 'Drive train' legend is affected too. + +A recent improvement is also that we can set the panel size via the theme. The `panel.widths` and `panel.heights` arguments take a unit (vector) and set the panels to this size. +If you are trying to coordinate panel sizes with `ggsave()`, please mind that other plot components, like axes, titles and legends also take up additional space. +If you have more than one panel in the vertical or horizontal direction, you can use a vector of units as demonstrated below for `widths`. + +```{r sub_panel_size} +p + + theme_sub_panel( + widths = unit(c(3, 5), "cm"), + heights = unit(4, "cm") + ) +``` + +It is also possible to set the total size of panels. +In the example above we can use `widths = unit(c(3, 3), "cm")` to have each panel be 3 centimetres wide, separated by a gap determined by the `panel.spacing.x` setting. +If we instead had used `widths = unit(6, "cm")` each panel would be smaller than 3 centimetres because the `panel.spacing.x` is included. + +### Strips + +The display text in strips is formatted by the `labeller` argument in the facets. +Styling this piece of text can be done with the `theme_sub_strip()` function, which replaces the `strip` prefix in `theme()`. +Similar to axes, strips also have positional variants with `background.x` and `background.y` specifying the backgrounds for horizontal and vertical strips specifically. + +The text even has specific `text.x.bottom`, `text.x.top`, `text.y.left` and `text.y.right` variants. +This allows text on the left to be rotated 90°, while text on the right is rotated -90°, which gives the sense that the text faces the panels. +Out of principle, you could force the `text.x.bottom` to be rotated 180° to achieve the same sense for horizontal text, but you may find out why readability trumps consistency. + +Another important distinction is the `placement` option, which affects how strips are displayed when they clash with axes. +This author personally thinks that `placement = "outside"` is the wiser choice 99% of the time. +When strips are displayed outside of axes, the `switch.pad.grid`/`switch.pad.wrap` elements control the spacing. + + +```{r sub_strip} +# We're including a labeller to showcase formatting +my_labeller <- as_labeller(c(`1999` = "The Nineties", `2008` = "The Noughties", + V = "Vertical Strip")) +p + + # Using a dummy strip for the vertical direction + facet_grid("V" ~ year, labeller = my_labeller, switch = "x") + + theme_sub_strip( + # All strip backgrounds + background = element_rect(fill = "cornsilk"), + # Specifically the horizontal strips + background.x = element_rect(colour = "black", linewidth = 1), + # Tweak text, specifically for the bottom strip + text.x.bottom = element_text(size = 16), + + placement = "outside", + # Spacing in between axes and strips. Note that it doesn't affect the + # vertical strip that doesn't have an axis. + switch.pad.grid = unit(1, "cm"), + clip = "off" + ) +``` + +The `clip = "on"` setting is the default and causes the strip border to be flush with the panel borders. +By turning the clipping off, the strip border bleeds out, but it also allows text to exceed the boundaries. + +### Axes + +Perhaps the most involved theme elements are the axis elements. +They have the longest chain of inheritance of all elements and have variants for every side of the plot. + +Let's start from the top and work our way down. +The `theme_sub_axis()` function lets you tweak all the axes at once. +Note that the axis line now appears in the left and bottom axes. + +```{r sub_axis} +# Turn on all lines +p + theme_sub_axis(line = element_line()) +``` + +To control the directions separately, you can use the `theme_sub_axis_x()` and `theme_sub_axis_y()` functions. + +```{r sub_axis_xy} +p + + # Turn on horizontal line + theme_sub_axis_x(line = element_line()) + + # Turn off ticks for vertical + theme_sub_axis_y(ticks = element_blank()) +``` + +If you are dealing with secondary axes, or you have placed your primary axes in unorthodox positions, you might find use in the even more granular `theme_sub_axis_*()` functions for the top, left, bottom and right positions. + +```{r sub_axis_positions} +p + + # Extra axes + guides(x.sec = "axis", y.sec = "axis") + + # Turning off ticks + theme_sub_axis_bottom(ticks = element_blank()) + + # Extra long, coloured ticks + theme_sub_axis_top( + ticks.length = unit(5, "mm"), + ticks = element_line(colour = "red") + ) + + # Extra spacing + theme_sub_axis_left(text = element_text(margin = margin_auto(10))) + + # Turning on the axis line + theme_sub_axis_right(line = element_line()) +``` + +In addition to being globally controlled by the theme, axes are guides that can also be locally controlled by their `guide_axis(theme)` argument. +The same theme elements apply, but they are accessed from the local theme that masks the global theme. +Note that besides from the colour changing, there is now also an axis line because the local `theme_classic()` draws axis lines. + +```{r axis_local_theme} +red_axis <- guide_axis(theme = theme_classic(ink = "red")) +p + guides(x = red_axis) +``` + +### Legend + +While the legend inheritance is typically straightforward, it can be a challenge to get these right. +To chop this problem in smaller pieces, we can separate the so called 'guide box' from the legend guides themselves. + +#### Guide box + +The guide box is a container for guides and is responsible for the placement and arrangement of its contents. + +```{r sub_legend_guidebox} +p + + theme_sub_legend( + # Showing the box + box.background = element_rect(fill = "cornsilk"), + + # Put legends on the left + position = "left", + + # Arrange legends horizontally + box = "horizontal", + + # Align to legend box to top + justification = "top", + # location = "plot", + # But align legends within the box at the bottom + box.just = "bottom", + + # Spacings and margins + box.margin = margin_auto(5), + box.spacing = unit(1, "cm") + ) +``` + +Legend boxes can be split up by manually specifying the `position` argument in guides. +You cannot tweak every box setting for every position independently. +However, the boxes can be justified individually. + +```{r sub_legend_guidebox_position} +p + + guides(shape = guide_legend(position = "left")) + + theme_sub_legend( + # Showing the boxes + box.background = element_rect(fill = "cornsilk"), + box.margin = margin_auto(5), + + # Tweaking the justification per position + justification.left = "top", + justification.right = "bottom" + ) +``` + +#### General legend guides + +Moving on from guide boxes to the guides themselves; +There are some theme settings that (almost) universally affect any guides, regardless of `guide_legend()`, `guide_colourbar()`, or `guide_bins()`. +These settings pertain to the legend background, margins, labels and titles and their placement and key sizes. + +```{r sub_legend_general} +p + + theme_sub_legend( + # Give guides a wider background + background = element_rect(fill = "cornsilk"), + margin = margin_auto(5, unit = "mm"), + + # Display legend titles to the right of the guide + title = element_text(angle = 270), + title.position = "right", + + # Display red labels to the left of the keys + text = element_text(colour = "red"), + text.position = "left", + + # Set smaller keys + key.width = unit(5, "mm"), + key.height = unit(5, "mm") + ) +``` + +#### Legend guide + +There are also settings that affect `guide_legend()` but not `guide_colourbar()`. +Most of these have to do with the arrangement of keys, like their spacing, justification or fill order (by row or column). +The `legend.key.justification` setting only matters when the text size exceeds the key size. +If we remove that setting from the plot below, the keys will fill up to fit the space. + +```{r sub_legend_legend} +p + + # Set two columns and long label text + scale_shape_discrete( + labels = c("4\nwheel\ndrive", "front\nwheel\ndrive", "rear\nwheel\ndrive"), + guide = guide_legend(ncol = 2) + ) + + theme_sub_legend( + # Fill items in grid in a row-wise fashion + byrow = TRUE, + # Increase spacing between keys + key.spacing.y = unit(5, "mm"), + key.spacing.x = unit(5, "mm"), + # Top-align keys with text + key.justification = "top" + ) +``` + +#### Colourbar guide + +Likewise, there are also settings specific to `guide_colourbar()`. +Generally, you can see it as a legend guide with a single elongated key. +This elongation has special behaviour in that the default is 5 times the original key size. +If you need to set the size directly without special behaviour, you can use the `guide_colourbar(theme)` argument. +Aside from the special size behaviour, we can also set the colourbar frame and ticks. + +```{r sub_legend_colourbar} +p + + # Using a local guide theme to directly set the size + guides(colour = guide_colourbar(theme = theme(legend.key.height = unit(5, "cm")))) + + theme_sub_legend( + frame = element_rect(colour = "red"), + # Long blue ticks + ticks = element_line(colour = "blue"), + ticks.length = unit(-5, "mm"), + # Adapt margins to accommodate longer ticks + text = element_text(margin = margin(l = 6, unit = "mm")), + margin = margin(l = 6, unit = "mm") + ) +``` + +A trick you can pull to have legends eat up all the available real estate, is to give them `"null"`-unit size. +Below, that trick stretches the colourbar across the full width of the plot. + +```{r stretchy_colourbar} +p + + guides(colour = guide_colourbar( + theme = theme_sub_legend( + key.width = unit(1, "null"), + title.position = "top", + margin = margin_auto(NA, 0) # remove left/right margins + ), + position = "bottom" + )) +``` + + +#### Binned legend + +A binned legend acts as a hybrid between a typical legend guide and a colourbar. +It depicts a discretised continuous (binned) legend, by properly displaying separate glyphs, but also displaying an axis with ticks at bin breaks. + +```{r sub_legend_binned} +p + + guides(colour = "bins") + + theme_sub_legend( + axis.line = element_line("red"), + ticks = element_line("blue") + ) +``` + +### Layers + +Since recently we can also set default choices for layer aesthetics via the theme. +We briefly saw this foreshadowed in the 'tweaking complete themes' section. +But you can have more granular control over layers as well, without affecting the entirety of the theme. + +#### Introducing the 'geom' element + +The new theme element powering all this is the `geom` argument. +It takes the return value of the `element_geom()` function to control the default graphical properties of layers. + +```{r layer_ink_paper} +p + + # Turn off grouping + aes(colour = NULL, shape = NULL) + + geom_smooth(formula = y ~ x, method = "lm") + + theme( + geom = element_geom( + ink = "tomato", + paper = "dodgerblue", + accent = "forestgreen" + ) + ) +``` + +The `element_geom()` function has a number of properties that we're about to describe. +Just like other `element_*()` function, it returns an object with properties, most of which are `NULL` by default. +These `NULL` properties will get filled in when the plot is built. + +```{r element_geom} +element_geom() +``` + +##### Colours + +There are 5 colour related settings. +In the plot above, we've already met three of them. + +* `ink` is the foreground colour. +* `paper` is the background colour. + It is often used in a mixture with `ink` to dull the foreground and coordinate with the rest of the theme. + You can see for example that the ribbon part of `geom_smooth()` is a bit purple-ish due to the mixture of reddish `ink` and bluish `paper`. +* `accent` is a speciality colour pick that only a few geoms use as default. + These are `geom_contour()`, `geom_quantile()` and `geom_smooth()`. + +The remaining two are well known to anyone who has worked with ggplot2 before: `colour` and `fill`. +These two overrule any `ink`/`paper`/`accent` setting to directly set colour and fill without any mixing. +For example, notice that the ribbon is a (semitransparent) purple, rather than a mixture with green paper. + + +```{r layer_colour_fill} +last_plot() + + theme(geom = element_geom( + fill = "purple", + colour = "orange", + paper = "green" # Ignored + )) +``` + +##### Lines + +There are also 4 different line settings. +You may already be familiar with `linewidth` and `linetype` setting how wide lines are, and how they are drawn respectively. +Additionally, we're now also using `borderwidth` and `bordertype` to denote these settings for closed shapes that can be filled, like the rectangles below. + +```{r layer_borderline} +ggplot(faithful, aes(eruptions)) + + geom_histogram(aes(y = after_stat(density)), bins = 30, colour = "black") + + geom_line(stat = "density") + + theme( + geom = element_geom( + # Applies to the bars + borderwidth = 0.5, + bordertype = "dashed", + # Applies to the line + linewidth = 4, + linetype = "solid" + ) + ) +``` + +##### Points and text + +The four remaining settings pertains to text and points. +Respectively `fontsize` and `pointsize` control the size. +`pointshape` and `family` control the shape and font family. + +```{r layer_pointtext} +ggplot(mtcars, aes(mpg, disp, label = rownames(mtcars))) + + geom_point() + + geom_label(nudge_x = 0.25, hjust = 0) + + theme( + geom = element_geom( + # Point settings + pointsize = 8, + pointshape = "←", + + # Text settings + fontsize = 8, + family = "Ink Free" + ) + ) + +``` + +##### Micro-managing layers + +Aside from globally affecting every layer via `theme(geom)`, you can also fine-tune the appearance of individual geometry types. +Whereas we envision `element_geom(ink, paper)` as the global 'aura' of a plot, the `element_geom(colour, fill)` is intended for tailoring specific geom types. +We can add theme elements for specific geoms by replacing the snake_case layer function name by dot.case argument name. +This works for layers that have an equivalent Geom ggproto class, which is the case for all geoms in ggplot2. + +```{r layer_granular} +ggplot(mpg, aes(class, displ)) + + geom_boxplot(outliers = FALSE) + + geom_jitter() + + theme( + geom.point = element_geom(colour = "dodgerblue"), + geom.boxplot = element_geom(fill = "orchid", colour = "turquoise") + ) +``` + +##### Macro-managing layers + +There are now various options for how to change non-data parts of layers, and it can be a bit tricky to determine when you should use what option. Essentially, this is a 2-by-2 table covering the option of which layers to set (single, all) and when it is used (local, global). + +* If you want to change the look of a single layer in a single plot, you can just use the static (unmapped) aesthetics in a layer. + For example: `geom_point(colour = "blue")`. + +* If you want to change the look of a single layer in all plots, you can use `update_theme()` to globally set a new (micro-managed) option. + For example: `update_theme(geom.point = element_geom(colour = "blue"))`. + You can also use the `element_geom(ink, paper)` settings but for single layers it may be more direct to use `element_geom(colour, fill)` instead. + We no longer recommend, and even discourage (!) using `update_geom_defaults()` for this purpose. + +* If you want to change the look of all layers in a single plot, you can use the `theme(geom)` argument and add it to a plot. + For example: `theme(geom = element_geom(ink = "blue"))`. + +* If you want to change the look of all layers in all plots, you can also use `update_theme()` to globally set the `geom` option. + For example: `update_theme(geom = element_geom(ink = "blue"))`. + Alternatively, you can also coordinate the entire theme by using for example `set_theme(theme_gray(ink = "blue"))`. + + +##### Access from layers + +Up to now, we've mostly described how to use the theme to instruct layers, but we can also instruct layers to lookup things from the theme too. +Using the `from_theme()` function in aesthetics allows you to use expressions with the variables present in `element_geom()`. +For example, if you want to use a darker variant of the `accent` colour instead of `ink`, you might want to write your mapping as follows: + +```{r layer_aesthetic} +p + aes(colour = from_theme(scales::col_darker(accent, 20))) +``` + +#### Palettes + +In addition to controlling the default aesthetics from the theme, you can also control the default palettes from the theme. +The palette theme settings all follow the following pattern, separated by dots: `palette`, aesthetic, type. +The `type` can be either `continuous` or `discrete`. +If you're using the default binned scale, it takes the continuous palette. +For example, if we want to change the default `shape` and `colour` palettes, we can declare that as follows: + +```{r palettes} +p + theme( + palette.shape.discrete = c("plus", "triangle", "diamond"), + palette.colour.continuous = c("maroon", "hotpink", "white") +) +``` + +The values of these palette theme elements are passed down to `scales::as_discrete_pal()` and `scales::as_continuous_pal()` for discrete and continuous scales respectively. + +### Theme elements in extensions + +Aside from extensions providing whole, complete themes, extensions may also define new theme elements. +You can sometimes see these in facets, coords or guide extensions. +With these wide use-cases, we cannot really describe these as much as just acknowledge they exist. +For example, the ggforce package has a zoom element that controls the appearance of zooming indicators. + +```{r extension_elements} +p + ggforce::facet_zoom(ylim = c(20, 30), xlim = c(3, 4)) + + theme(zoom = element_rect(colour = "red", linewidth = 0.2, fill = NA)) +``` + +If you are writing your own extension and need to compute a bespoke element from the theme, you can use `register_theme_elements()` to ensure ggplot2 knows about your element and can use it in `calc_element()`. + +```{r calc_element} +# A custom element comes up empty +calc_element("my_element", complete_theme()) + +# Register element +register_theme_elements( + my_element = element_rect(), + element_tree = list( + my_element = el_def( + class = "element_rect", # Must be a rect element + inherit = "rect" # Get settings from theme(rect) + ) + ) +) + +# Now custom element can be computed +calc_element("my_element", complete_theme()) +``` + +## Writing your own theme + +When you are writing your own theme there are a few things to keep in mind. +A guiding principle is to write your themes such that it is robust to upstream changes. +Not only can ggplot2 add, deprecate or reroute elements, also theme elements used by extensions should be accommodated. + +#### 1. Use a function + +First, this principle means that you should write your theme as a function. +Writing your theme as a function ensures it can be rebuild. +This is opposed to assigning a theme object to a variable in your package's namespace ---or heaven forbid--- save it as a file, +If you assign your theme object to a variable in your namespace, the object will get compiled into your code and can cause build time warnings or errors if an element function or argument get updated. + +```{r theme_as_function} +my_theme <- function(...) {} +``` + +#### 2. Use a base theme + +Secondly, it is good practise to start your own theme as a function that calls a complete theme function as its base. +It ensures that when ggplot2 adds new elements that belong in complete themes, your theme also remains complete. + +```{r theme_use_base} +my_theme <- function(...) { + theme_gray(...) +} +``` + +### 3. Use `theme()` to add elements + +Third, you should use `theme()` to add new elements to the base. +While it is technically possible to assign additional elements by sub-assignment (`$<-`), we strong advice against this. +Using `theme()` ensures that any deprecated arguments are redirected to an appropriate place. + +```{r theme_dontdothis} +# Do *not* do the following! +my_fragile_theme <- function(...) { + t <- theme_gray(...) + t$legend.text <- element_text() # BAD + t +} +``` + +You can use `+ theme()` or `%+replace% theme()`, where `+` merges elements and `%+replace%` replaces elements by completely removing old settings. If you use `%+replace%` for a root element, like `text` or `line`, you should take care that every property has non-null values. + +```{r theme_adding_parts} +my_theme <- function(...) { + theme_gray(...) %+replace% + theme( + # Because we're replacing, we should fully define root elements + text = element_text( + family = "", face = "plain", colour = "red", size = 11, + hjust = 0.5, vjust = 0.5, angle = 0, lineheight = 1, margin = margin() + ), + # Non-root elements can be partially defined + legend.text = element_text(colour = "blue") + ) + + # Here we're updating the root line element with `+`, instead of replacing it + theme(line = element_line(linetype = "dotted")) +} + +p + my_theme() +``` + +#### 4. Caching themes + +We mentioned in 1. that you shouldn't assign a theme object to a variable in your namespace. +However, you may want to reuse a theme without having to reconstruct it every time because you may never need to change arguments in your package. +The solution we recommend for this use case, is to cache your theme when your package is loaded. +It ensures that we observe all the formalities of building a theme, with all the protections this offers, but we need to do this only once per session. + +```{r theme_caching} +# Create a variable for your future theme +cached_theme <- NULL + +# In your .onLoad function, construct the theme +.onLoad <- function(libname, pkgname) { + cached_theme <<- my_theme() +} + +# In your package's functions, you can now use the cached theme +my_plotting_function <- function() { + ggplot(mpg, aes(displ, hwy)) + + geom_point() + + cached_theme +} + +# Simulate loading +.onLoad() + +# Works! +my_plotting_function() +``` + +## Tips and tricks + +### Global theme + +Are you also used to writing entire booklets of theme settings at every plot? +Do your fingers tire of typing `panel.background = element_blank()` dozens of times in a script? +Worry no more! +Set your theme settings to permanent today by using the one-time offer of `set_theme()`! + +```{r theme_set} +my_theme <- function(...) { + theme_gray() + + theme( + panel.background = element_blank(), + panel.grid = element_line(colour = "grey95"), + palette.colour.continuous = "viridis" + ) +} + +set_theme(my_theme()) + +# Global goodness galore! +p +``` + +To undo any globally set theme, you can use `reset_theme_settings()`. + +### Fonts + +Setting the typography of your plots is important and discussed more thoroughly in [this blog post](https://www.tidyverse.org/blog/2025/05/fonts-in-r/). +Here we're simply giving the suggestion to use the `systemfonts::require_font()` when you are writing theme functions that include special fonts. +It will not cover font behaviour for every graphics device, but it will for devices that use [systemfonts](https://systemfonts.r-lib.org/) for finding fonts, like [ragg](https://ragg.r-lib.org/) and [svglite](https://svglite.r-lib.org/). + +```{r fonts} +my_theme <- function(header_family = "Impact", ...) { + systemfonts::require_font(header_family) + theme_gray(header_family = header_family, ...) +} + +p + my_theme() +``` + +### Bundling theme settings + +Not every theme needs to be a complete theme. +You can write partial themes that bundle together related settings to achieve an effect you want. +For example, here are some settings that left-aligns the title and legend at the top of a plot. + +```{r part_theme_upper_legend} +upper_legend <- function() { + theme( + plot.title.position = "plot", + legend.location = "plot", + legend.position = "top", + legend.justification.top = "left", + legend.title.position = "top", + legend.margin = margin_part(l = 0) + ) +} + +p + + aes(colour = NULL) + + upper_legend() +``` + +Another example for bottom placement of colour bars: + +```{r part_theme_bottom_colourbar} +bottom_colourbar <- function() { + theme_sub_legend( + position = "bottom", + title.position = "top", + justification.bottom = "left", + # Stretch bar across width of panels + key.width = unit(1, "null"), + margin = margin_part(l = 0, r = 0) + ) +} + +p + + aes(shape = NULL) + + bottom_colourbar() +``` + +If you don't mind venturing outside the grammar for a brisk stroll, you can also bundle theme settings together with other components. +For example, in a bar chart you may wish to suppress vertical grid lines and not expand the y-axis at the bottom. + +```{r part_theme_barchart} +barchart_settings <- function() { + list( + theme(panel.grid.major.x = element_blank()), + coord_cartesian(expand = c(bottom = FALSE)) + ) +} + +ggplot(mpg, aes(class)) + + geom_bar() + + barchart_settings() +``` + +The point here is not to make an exhaustive list of all useful bundles, it is to highlight that it possible to create reusable chunks of theme. + +### Pattern rectangles + +Did you know that `element_rect(fill)` can be a grid pattern? +You can use it to place images in the panel background, which can be neat for branding. + +```{r pattern_fill} +pattern <- "https://raw.githubusercontent.com/tidyverse/ggplot2/refs/heads/main/man/figures/logo.png" |> + magick::image_read() |> + grid::rasterGrob( + x = 0.8, y = 0.8, + width = unit(0.2, "snpc"), + height = unit(0.23, "snpc"), + ) |> + grid::pattern(extend = "none") + +p + + theme( + panel.background = element_rect(fill = pattern), + # legend.key inherits from panel background, so we tweak it + legend.key = element_blank(), + # make grid semitransparent to lay over pattern + panel.grid = element_line(colour = alpha("black", 0.05)) + ) +``` + +## Finally + +This article has been light on advice on how you should or should not use themes. +Mostly, this is to encourage experimentation. +Don't be afraid to put in a personal twist. +Make mistakes. +Discover why a theme does or doesn't work for a plot. +If you cannot be bothered, there are [extension packages](https://exts.ggplot2.tidyverse.org/gallery/) that offer plenty of options. +The [tidytuesday](https://github.com/rfordatascience/tidytuesday) project has spawned a rich source of varied plotting code, including themes people use. +If you like a tidytuesday plot, find the source code and see how the sausage is made. +Find whatever theme works for you and your plots. diff --git a/content/blog/ggplot2-styling/index.md b/content/blog/ggplot2-styling/index.md new file mode 100644 index 000000000..a16c85a37 --- /dev/null +++ b/content/blog/ggplot2-styling/index.md @@ -0,0 +1,1344 @@ +--- +output: hugodown::md_document + +slug: ggplot2-styling +title: ggplot2 styling +date: 2025-10-01 +author: Teun van den Brand +description: > + This post discusses one function in ggplot2: `theme()`. Find out about the glamour of graphics in this deep-dive article. + +photo: + url: https://www.pexels.com/photo/people-dressed-in-elaborate-costumes-for-venetian-masqueade-5932619 + author: Helena Jankovičová Kováčová + +# one of: "deep-dive", "learn", "package", "programming", "roundup", or "other" +categories: [package] +tags: [] +rmd_hash: ebbc03cc3a02d813 +html_dependencies: +- +- +- +- +- +- +- +- +- + +--- + + + +## So you want to style your plot? + +Diligently, you have read, cleaned and modelled your data. You have carefully crafted a plot that lets your data speak its story. Now it is time to polish. Now it is time to let your visualisation shine. + +We will set out to illuminate how to set the stylistic finishing touches on your visualisations made with the ggplot2 package. The ggplot2 package has had a [recent release](https://www.tidyverse.org/blog/2025/09/ggplot2-4-0-0/) that included some relevant changes to styling plots. In ggplot2, the theme system is responsible for many non-data aspects of how your plot looks. It covers anything from panels, to axes, titles and legends. Here, we'll get started with digesting important parts of the theme system. We'll start with complete themes, get into theme elements followed by how these elements are used in various parts of the plot and finish off with some tips, including how to write your own theme functions. Before we begin discussing themes, let's make an example plot that can showcase many aspects. + +
+ +
+ +
+ +
library(ggplot2)
+
+p <- ggplot(mpg, aes(displ, hwy, colour = cty, shape = drv)) +
+  geom_point() +
+  facet_grid(~ year) +
+  labs(
+    title = "Fuel efficiency",
+    subtitle = paste0("Described for ", nrow(mpg), " cars from 1999 and 2008"),
+    caption = "Source: U.S. Environmental Protection Agency",
+    x = "Engine Displacement",
+    y = "Highway miles per gallon",
+    colour = "City miles\nper gallon",
+    shape = "Drive train"
+  )
+
+p
+ +
+ +
+ +
+ + +
+ +If you haven't already accidentally triggered it, feel free to hover your mouse over the plot above. Hovering will tell you what theme element you are pointing at. + +## What is a theme? + +In ggplot, a theme is a list of descriptions for various parts of the plot. It is where you can set the size of your titles, the colours of your panels, the thickness of your grid lines and placement of your legends. + +Themes are declared using the [`theme()`](https://ggplot2.tidyverse.org/reference/theme.html) function, which populates these descriptions called 'theme elements'. Some of these elements have a predefined set of properties and can be set using the element functions, like [`element_text()`](https://ggplot2.tidyverse.org/reference/element.html). Other theme elements can take simpler values like strings, numbers or units. + +Some pre-arranged collections of elements can be found in complete themes, like the iconic [`theme_gray()`](https://ggplot2.tidyverse.org/reference/ggtheme.html). These are convenient ways to quickly swap out the complete look of a plot. + +## Complete themes + +Let's start big and work our way through the more nitty-gritty aspects of theming plots. The most thorough way to change the styling of a single plot is to swap out the complete theme. You can do this simply by adding one of the `theme_*()` functions, like [`theme_minimal()`](https://ggplot2.tidyverse.org/reference/ggtheme.html). + +
+ +
p + theme_minimal()
+
+ + +
+ +### Built-in themes + +The base ggplot2 package already comes with a series of 9 built-in complete themes. For the sake of completeness about complete themes, they are displayed in the fold-out sections below. You can peruse them at your leisure to help you pick one you might like. + +

+

+ +theme_grey() (default) + + +
+ +
p + theme_grey()
+
+ + +
+ +
+

+

+

+ +theme_bw() + + +
+ +
p + theme_bw()
+
+ + +
+ +
+

+

+

+ +theme_linedraw() + + +
+ +
p + theme_linedraw()
+
+ + +
+ +
+

+

+

+ +theme_light() + + +
+ +
p + theme_light()
+
+ + +
+ +
+

+

+

+ +theme_dark() + + +
+ +
p + theme_dark()
+
+ + +
+ +
+

+

+

+ +theme_minimal() + + +
+ +
p + theme_minimal()
+
+ + +
+ +
+

+

+

+ +theme_classic() + + +
+ +
p + theme_classic()
+
+ + +
+ +
+

+

+

+ +theme_void() + + +
+ +
p + theme_void()
+
+ + +
+ +
+

+

+

+ +theme_test() + + +
+ +
p + theme_test()
+
+ + +
+ +
+

+ +### Additional themes + +Some packages come with their own themes that you can add to your plots. For example the cowplot package has a theme that galvanises you to not use [labels that are too small](https://clauswilke.com/dataviz/small-axis-labels.html), and otherwise has a clean look. + +

+

+ +cowplot::theme_cowplot() + + +
+ +
p + cowplot::theme_cowplot()
+
+ + +
+ +
+

+ +The ggthemes package hosts themes that reflect other popular venues of data visualisation, such as the economist or FiveThirtyEight. + +

+

+ +ggthemes::theme_fivethirtyeight() + + +
+ +
p + ggthemes::theme_fivethirtyeight()
+
+ + +
+ +
+

+ +If the moods strikes you for a more playful plot, you can use the tvthemes package to style your plot according to TV shows! + +

+

+ +tvthemes::theme_simpsons() + + +
+ +
p + tvthemes::theme_simpsons()
+
+ + +
+ +
+

+ +Aside from these packages that live on CRAN, there are also non-CRAN packages that come with complete themes. You can visit the [extension gallery](https://exts.ggplot2.tidyverse.org/gallery/) and filter on the 'themes' tag to find more packages. + +### Tweaking complete themes + +The complete themes have arguments that affect multiple components across the plot. Perhaps the most well known is the `base_size` argument that globally controls the size of theme elements, ranging from the text sizes, to line widths, and ---since recently--- even point sizes. + +
+ +
p + theme_bw(base_size = 8)
+
+ + +
+ +A technique used to distinguish visual hierarchy is 'font pairing', meaning that you combine more than one font to convey visual hierarchy. In web design, it means displaying your headers different from your body text. In data visualisation, it can mean displaying your titles distinctly from labels. The most common pairing, and the default one baked into ggplot2, is to display titles larger than labels in the same typeface. Another popular choice is to use different weights, like 'bold' and 'plain'. It is now also easier to use different typefaces by pairing the `header_family` and the `base_family` fonts together. In the example below, we pair a serif font for headers and a sans-serif font for the rest. + +
+ +
p + theme_bw(base_family = "Roboto", header_family = "Roboto Slab")
+
+ + +
+ +A recent addition to styling with complete themes are colour choices. The `ink` argument roughly amounts to the colour for all foreground elements, like text, lines and points. This is complemented by the `paper` argument, which affect background elements like the panels and plot background. Lastly, there is an `accent` argument which controls the display of a few specific layers, like [`geom_smooth()`](https://ggplot2.tidyverse.org/reference/geom_smooth.html) or [`geom_contour()`](https://ggplot2.tidyverse.org/reference/geom_contour.html). For some aspects of the plot, the `ink` and `paper` arguments are mixed to produce intermediate colours. As an example, when we use [`theme_bw()`](https://ggplot2.tidyverse.org/reference/ggtheme.html), the strip fill colour is a mix between the foreground and background to slightly lift this part from the background. The `ink` and `paper` arguments can also be used to quickly recolour a plot, or to convert a plot to 'dark mode' by using a light `ink` and dark `paper`. + +
+ +
p + 
+  # Turning off these aesthetics to prevent grouping
+  aes(shape = NULL, colour = NULL) +
+  geom_smooth(method = "lm", formula = y ~ x) +
+  theme_bw(
+    ink = "#BBBBBB", 
+    paper = "#333333", 
+    accent = "red"
+  )
+
+ + +
+ +## Theme elements + +Rather than swapping out complete themes in one fell swoop, themes can also be tweaked to various degrees. In ggplot2, themes are a collection of theme elements, where an element describes a property, or set of properties, for a part of the theme. + +### Element functions + +The documentation in `?theme()` will tell you what type of input each theme element will expect. Some theme elements just expect scalar values and not collections of properties. You can simply set these in the theme directly. For example, we all know that the golden ratio is the best ratio, so we can use it in our plot as follows: + +
+ +
phi <- (1 + sqrt(5)) / 2
+p + theme(aspect.ratio = phi)
+
+ + +
+ +In the cases where a cohesive set of properties serves as a theme element, ggplot2 has `element_*()` functions. One of the simpler elements is [`element_line()`](https://ggplot2.tidyverse.org/reference/element.html) and we can declare a new set of line properties as follows: + +
+ +
red_line <- element_line(colour = "red", linewidth = 2)
+red_line
+#> <ggplot2::element_line>
+#>  @ colour       : chr "red"
+#>  @ linewidth    : num 2
+#>  @ linetype     : NULL
+#>  @ lineend      : NULL
+#>  @ linejoin     : NULL
+#>  @ arrow        : logi FALSE
+#>  @ arrow.fill   : chr "red"
+#>  @ inherit.blank: logi FALSE
+
+ +
+ +These elements can then be given to the [`theme()`](https://ggplot2.tidyverse.org/reference/theme.html) function to assign these properties to a specific part of the theme, like the `axis.line` in this example. + +
+ +
p + theme(axis.line = red_line)
+
+ + +
+ +Below is an overview of elements and some common places where they are used: + +
+ +| Element | Description | +|:--------------------|:--------------------------------------------------| +| [`element_blank()`](https://ggplot2.tidyverse.org/reference/element.html) | Indicator to skip drawing an element. | +| [`element_line()`](https://ggplot2.tidyverse.org/reference/element.html) | Used for axis lines, grid lines and tick marks. | +| [`element_rect()`](https://ggplot2.tidyverse.org/reference/element.html) | Used for (panel) backgrounds, borders and strips. | +| [`element_text()`](https://ggplot2.tidyverse.org/reference/element.html) | Used for (sub)titles, labels, captions. | +| [`element_geom()`](https://ggplot2.tidyverse.org/reference/element.html) | Used to set default properties of layers. | +| [`element_polygon()`](https://ggplot2.tidyverse.org/reference/element.html) | Not used, but provided for reasons of extension. | +| [`element_point()`](https://ggplot2.tidyverse.org/reference/element.html) | Not used, but provided for reasons of extension. | + +
+ +In addition to these elements in ggplot2, extension packages can also define custom elements. Generally speaking, these elements are variants of the elements listed above and often have slightly different properties and are rendered differently. For example [`marquee::element_marquee()`](https://marquee.r-lib.org/reference/element_marquee.html) is a subclass of [`element_text()`](https://ggplot2.tidyverse.org/reference/element.html), but interprets the provided text as markdown. It applies some formatting like `**` for bold, or allows for custom spans like `{.red ...}`. Another example is [`ggh4x::element_part_rect()`](https://teunbrand.github.io/ggh4x/reference/element_part_rect.html) that can draw a subset of rectangle borders. + +
+ +
p +
+  labs(title = "**Fuel** {.red efficiency}") +
+  theme(
+    plot.title = marquee::element_marquee(),
+    strip.background = ggh4x::element_part_rect(colour = "black", side = "b")
+  )
+
+ + +
+ +### Hierarchy and inheritance + +Most theme elements are hierarchical. At the root, they are broadly applicable and change large parts of the plot. At leaves, they are very specific and allow fine grained control. Travelling from roots to leaves, properties of theme elements are inherited from parent to child. Some inheritance is very direct, where leaves directly inherit from roots (for example `legend.text`). Other times, inheritance is more arduous, like for `axis.minor.ticks.y.left`: it inherits from `axis.ticks.y.left`, which inherits from `axis.ticks.y`, which inherits from `axis.ticks`, which finally inherits from `line`. Most often, elements only have a single parent, but there are subtle exceptions. + +In the example below we set the root `text` element to red text. This is applied (almost) universally to all text in the plot. We also set the font of the leaf `legend.text` element. We see that not only has the legend text font changed, but it is red as well because of the root `text` element. + +
+ +
p + theme(
+  # A root element
+  text = element_text(colour = "red"),
+  # A leaf element
+  legend.text = element_text(family = "impact")
+)
+
+ + +
+ +However, the keen eye spots that the strip text and axis text are *not* red. This is because in the line of succession, an ancestor declared a different colour property for the text, which overrules the colour property descending from the root `text` element. In these specific cases, the deviating ancestors are `axis.text` and `strip.text`. + +When we inspect the contents of a theme element, we may find that the elements are `NULL`. This is simply an indicator that this element will inherit from its ancestor *in toto*. Another possibility is that some properties of an element are `NULL`. A `NULL` property means that the property will be inherited from the parent. When we truly want to know what properties are taken to display a theme element, we can use the [`calc_element()`](https://ggplot2.tidyverse.org/reference/calc_element.html) function to resolve the inheritance and populate all the fields. + +
+ +
# Will inherit entirely from parent
+theme_gray()$axis.ticks.x.bottom
+#> NULL
+
+# The element is incomplete
+theme_gray()$axis.ticks
+#> <ggplot2::element_line>
+#>  @ colour       : chr "#333333FF"
+#>  @ linewidth    : NULL
+#>  @ linetype     : NULL
+#>  @ lineend      : NULL
+#>  @ linejoin     : NULL
+#>  @ arrow        : logi FALSE
+#>  @ arrow.fill   : chr "#333333FF"
+#>  @ inherit.blank: logi TRUE
+
+# Proper way to access the properties of an element
+calc_element("axis.ticks.x.bottom", theme_gray())
+#> <ggplot2::element_line>
+#>  @ colour       : chr "#333333FF"
+#>  @ linewidth    : num 0.5
+#>  @ linetype     : num 1
+#>  @ lineend      : chr "butt"
+#>  @ linejoin     : chr "round"
+#>  @ arrow        : logi FALSE
+#>  @ arrow.fill   : chr "#333333FF"
+#>  @ inherit.blank: logi TRUE
+
+ +
+ +The [`?theme`](https://ggplot2.tidyverse.org/reference/theme.html) documentation often tells you how the elements inherit and [`calc_element()`](https://ggplot2.tidyverse.org/reference/calc_element.html) will resolve it for you. If, for some reason, you need programmatic access to the inheritance tree, you can use [`get_element_tree()`](https://ggplot2.tidyverse.org/reference/register_theme_elements.html). Let's say you want to find out exactly which elements have multiple parents. The resulting object is the internal structure ggplot2 uses to resolve inheritance and has an `inherit` field for every element that discerns its direct parent. + +
+ +
tree <- get_element_tree()
+tree$axis.line.x.bottom$inherit
+#> [1] "axis.line.x"
+
+ +
+ +## Anatomy of a theme + +
+ +
+ +The [`theme()`](https://ggplot2.tidyverse.org/reference/theme.html) function has a lot of arguments and can be a bit overwhelming to parse in one take. At the time of writing, it has 147 arguments and `...` is obfuscating additional options. Because we like structure rather than chaos, let us try to digest the [`theme()`](https://ggplot2.tidyverse.org/reference/theme.html) function one bite at a time. Much of the theme has been divided over parts in the `theme_sub_*()` family of functions. This family are just simple shortcuts. For example the `theme_sub_axis(title)` argument, populates the `axis.title` element. + +
+ +
theme_sub_axis(title = element_blank())
+#> <theme> List of 1
+#>  $ axis.title: <ggplot2::element_blank>
+#>  @ complete: logi FALSE
+#>  @ validate: logi TRUE
+
+ +
+ +If you're redefining a series of related settings, it can be beneficial to use the `theme_sub_*()`. One benefit is brevity. For example, if you want to tweak the left y-axis a lot, it can be terser to use `theme_sub_axis_left(title, text, ticks)` rather than `theme(axis.title.y.left, axis.text.y.left, axis.ticks.y.left)`. The second benefit is that it helps organising your theme, preserving a shred of sanity while hatching your plots. + +### Whole plot + +There are a series of mostly textual theme elements that mostly display outside the plot itself. Using the [`theme_sub_plot()`](https://ggplot2.tidyverse.org/reference/subtheme.html) function, we can omit the `plot` prefix in the settings. We can us it to control the background, as well as the titles, caption and tag text and their placement. In the plot below, we're tweaking these settings to show the scope. Note that the text (except for the tag) is now aligned across the plot as a whole, rather than aligned with the panels. + +
+ +
p + 
+  labs(tag = "A") +
+  theme_sub_plot(
+    # Adjust the background colour
+    background = element_rect(fill = "cornsilk"),
+    
+    # Align title and subtitle to plot instead of panels
+    title = element_text(hjust = 0), # default,
+    subtitle = element_text(colour = "dodgerblue"),
+    title.position = "plot", 
+    
+    # Align caption to plot instead of panels
+    caption = element_text(hjust = 1), # default
+    caption.position = "plot",
+    
+    # Place the tag in the top right of the panels instead of top left of plot
+    tag.position = "topright",
+    tag.location = "panel"
+  )
+
+ + +
+ +### Panels + +An important aspect of the panels are the grid lines. The grid lines follow the major and minor breaks of the scale, which is also the major distinction in how they are displayed. The next distinction is whether the lines are horizontal and mark breaks vertically (`y`) or the lines are vertical and mark breaks horizontally (`x`). + +
+ +
p + 
+  theme_sub_panel(
+    # Extra space between panels
+    spacing.x = unit(1, "cm"),
+    
+    # Tweaking all the grid elements
+    grid = element_line(colour = "grey80"),
+    
+    # Turning off the minor grid elements
+    grid.minor = element_blank(),
+    
+    # Tweak the major x/y lines separately
+    grid.major.x = element_line(linetype = "dotted"),
+    grid.major.y = element_line(colour = "white")
+  )
+
+ + +
+ +Besides grid lines, also the border and the background are important for the panel styling. They can be confusing because they are similar, but not identical. Notably, the panel background is underneath the data (unless `ontop = TRUE`), while the panel border is on top of the panel. You can see this in the plot below, because the white grid lines are visible over the blue background, but not over the red border. + +
+ +
p +
+  theme_sub_panel(
+    background = element_rect(fill = "cornsilk", colour = "blue", linewidth = 6),
+    border     = element_rect(colour = "red", linewidth = 3, fill = "black"),
+  )
+
+ + +
+ +Both the background and the border are clipped by the coordinate systems clipping setting, e.g. `coord_cartesian(clip)`. It should also be noted that any `fill` property set on the border is ignored. Moreover, the legend key background takes on the appearance of the panel background by default, which is why the 'Drive train' legend is affected too. + +A recent improvement is also that we can set the panel size via the theme. The `panel.widths` and `panel.heights` arguments take a unit (vector) and set the panels to this size. If you are trying to coordinate panel sizes with [`ggsave()`](https://ggplot2.tidyverse.org/reference/ggsave.html), please mind that other plot components, like axes, titles and legends also take up additional space. If you have more than one panel in the vertical or horizontal direction, you can use a vector of units as demonstrated below for `widths`. + +
+ +
p + 
+  theme_sub_panel(
+    widths = unit(c(3, 5), "cm"),
+    heights = unit(4, "cm")
+  )
+
+ + +
+ +It is also possible to set the total size of panels. In the example above we can use `widths = unit(c(3, 3), "cm")` to have each panel be 3 centimetres wide, separated by a gap determined by the `panel.spacing.x` setting. If we instead had used `widths = unit(6, "cm")` each panel would be smaller than 3 centimetres because the `panel.spacing.x` is included. + +### Strips + +The display text in strips is formatted by the `labeller` argument in the facets. Styling this piece of text can be done with the [`theme_sub_strip()`](https://ggplot2.tidyverse.org/reference/subtheme.html) function, which replaces the `strip` prefix in [`theme()`](https://ggplot2.tidyverse.org/reference/theme.html). Similar to axes, strips also have positional variants with `background.x` and `background.y` specifying the backgrounds for horizontal and vertical strips specifically. + +The text even has specific `text.x.bottom`, `text.x.top`, `text.y.left` and `text.y.right` variants. This allows text on the left to be rotated 90°, while text on the right is rotated -90°, which gives the sense that the text faces the panels. Out of principle, you could force the `text.x.bottom` to be rotated 180° to achieve the same sense for horizontal text, but you may find out why readability trumps consistency. + +Another important distinction is the `placement` option, which affects how strips are displayed when they clash with axes. This author personally thinks that `placement = "outside"` is the wiser choice 99% of the time. When strips are displayed outside of axes, the `switch.pad.grid`/`switch.pad.wrap` elements control the spacing. + +
+ +
# We're including a labeller to showcase formatting
+my_labeller <- as_labeller(c(`1999` = "The Nineties", `2008` = "The Noughties", 
+                             V = "Vertical Strip"))
+p + 
+  # Using a dummy strip for the vertical direction
+  facet_grid("V" ~ year, labeller = my_labeller, switch = "x") +
+  theme_sub_strip(
+    # All strip backgrounds
+    background = element_rect(fill = "cornsilk"),
+    # Specifically the horizontal strips
+    background.x = element_rect(colour = "black", linewidth = 1),
+    # Tweak text, specifically for the bottom strip
+    text.x.bottom = element_text(size = 16),
+    
+    placement = "outside",
+    # Spacing in between axes and strips. Note that it doesn't affect the 
+    # vertical strip that doesn't have an axis.
+    switch.pad.grid = unit(1, "cm"),
+    clip = "off"
+  )
+
+ + +
+ +The `clip = "on"` setting is the default and causes the strip border to be flush with the panel borders. By turning the clipping off, the strip border bleeds out, but it also allows text to exceed the boundaries. + +### Axes + +Perhaps the most involved theme elements are the axis elements. They have the longest chain of inheritance of all elements and have variants for every side of the plot. + +Let's start from the top and work our way down. The [`theme_sub_axis()`](https://ggplot2.tidyverse.org/reference/subtheme.html) function lets you tweak all the axes at once. Note that the axis line now appears in the left and bottom axes. + +
+ +
# Turn on all lines
+p + theme_sub_axis(line = element_line())
+
+ + +
+ +To control the directions separately, you can use the [`theme_sub_axis_x()`](https://ggplot2.tidyverse.org/reference/subtheme.html) and [`theme_sub_axis_y()`](https://ggplot2.tidyverse.org/reference/subtheme.html) functions. + +
+ +
p +
+  # Turn on horizontal line
+  theme_sub_axis_x(line = element_line()) +
+  # Turn off ticks for vertical
+  theme_sub_axis_y(ticks = element_blank())
+
+ + +
+ +If you are dealing with secondary axes, or you have placed your primary axes in unorthodox positions, you might find use in the even more granular `theme_sub_axis_*()` functions for the top, left, bottom and right positions. + +
+ +
p +
+  # Extra axes
+  guides(x.sec = "axis", y.sec = "axis") +
+  # Turning off ticks
+  theme_sub_axis_bottom(ticks = element_blank()) +
+  # Extra long, coloured ticks
+  theme_sub_axis_top(
+    ticks.length = unit(5, "mm"),
+    ticks = element_line(colour = "red")
+  ) +
+  # Extra spacing
+  theme_sub_axis_left(text = element_text(margin = margin_auto(10))) +
+  # Turning on the axis line
+  theme_sub_axis_right(line = element_line())
+
+ + +
+ +In addition to being globally controlled by the theme, axes are guides that can also be locally controlled by their `guide_axis(theme)` argument. The same theme elements apply, but they are accessed from the local theme that masks the global theme. Note that besides from the colour changing, there is now also an axis line because the local [`theme_classic()`](https://ggplot2.tidyverse.org/reference/ggtheme.html) draws axis lines. + +
+ +
red_axis <- guide_axis(theme = theme_classic(ink = "red"))
+p + guides(x = red_axis)
+
+ + +
+ +### Legend + +While the legend inheritance is typically straightforward, it can be a challenge to get these right. To chop this problem in smaller pieces, we can separate the so called 'guide box' from the legend guides themselves. + +#### Guide box + +The guide box is a container for guides and is responsible for the placement and arrangement of its contents. + +
+ +
p + 
+  theme_sub_legend(
+    # Showing the box
+    box.background = element_rect(fill = "cornsilk"),
+    
+    # Put legends on the left
+    position = "left",
+    
+    # Arrange legends horizontally
+    box = "horizontal",
+    
+    # Align to legend box to top
+    justification = "top",
+    # location = "plot",
+    # But align legends within the box at the bottom
+    box.just = "bottom",
+    
+    # Spacings and margins
+    box.margin = margin_auto(5),
+    box.spacing = unit(1, "cm")
+  )
+
+ + +
+ +Legend boxes can be split up by manually specifying the `position` argument in guides. You cannot tweak every box setting for every position independently. However, the boxes can be justified individually. + +
+ +
p +
+  guides(shape = guide_legend(position = "left")) +
+  theme_sub_legend(
+    # Showing the boxes
+    box.background = element_rect(fill = "cornsilk"),
+    box.margin = margin_auto(5),
+    
+    # Tweaking the justification per position
+    justification.left = "top",
+    justification.right = "bottom"
+  )
+
+ + +
+ +#### General legend guides + +Moving on from guide boxes to the guides themselves; There are some theme settings that (almost) universally affect any guides, regardless of [`guide_legend()`](https://ggplot2.tidyverse.org/reference/guide_legend.html), [`guide_colourbar()`](https://ggplot2.tidyverse.org/reference/guide_colourbar.html), or [`guide_bins()`](https://ggplot2.tidyverse.org/reference/guide_bins.html). These settings pertain to the legend background, margins, labels and titles and their placement and key sizes. + +
+ +
p +
+  theme_sub_legend(
+    # Give guides a wider background
+    background = element_rect(fill = "cornsilk"),
+    margin = margin_auto(5, unit = "mm"),
+    
+    # Display legend titles to the right of the guide
+    title = element_text(angle = 270),
+    title.position = "right",
+    
+    # Display red labels to the left of the keys
+    text = element_text(colour = "red"),
+    text.position = "left",
+    
+    # Set smaller keys
+    key.width = unit(5, "mm"),
+    key.height = unit(5, "mm")
+  )
+
+ + +
+ +#### Legend guide + +There are also settings that affect [`guide_legend()`](https://ggplot2.tidyverse.org/reference/guide_legend.html) but not [`guide_colourbar()`](https://ggplot2.tidyverse.org/reference/guide_colourbar.html). Most of these have to do with the arrangement of keys, like their spacing, justification or fill order (by row or column). The `legend.key.justification` setting only matters when the text size exceeds the key size. If we remove that setting from the plot below, the keys will fill up to fit the space. + +
+ +
p + 
+  # Set two columns and long label text
+  scale_shape_discrete(
+    labels = c("4\nwheel\ndrive", "front\nwheel\ndrive", "rear\nwheel\ndrive"),
+    guide = guide_legend(ncol = 2)
+  ) +
+  theme_sub_legend(
+    # Fill items in grid in a row-wise fashion
+    byrow = TRUE,
+    # Increase spacing between keys
+    key.spacing.y = unit(5, "mm"),
+    key.spacing.x = unit(5, "mm"),
+    # Top-align keys with text
+    key.justification = "top"
+  )
+
+ + +
+ +#### Colourbar guide + +Likewise, there are also settings specific to [`guide_colourbar()`](https://ggplot2.tidyverse.org/reference/guide_colourbar.html). Generally, you can see it as a legend guide with a single elongated key. This elongation has special behaviour in that the default is 5 times the original key size. If you need to set the size directly without special behaviour, you can use the `guide_colourbar(theme)` argument. Aside from the special size behaviour, we can also set the colourbar frame and ticks. + +
+ +
p +
+  # Using a local guide theme to directly set the size
+  guides(colour = guide_colourbar(theme = theme(legend.key.height = unit(5, "cm")))) +
+  theme_sub_legend(
+    frame = element_rect(colour = "red"),
+    # Long blue ticks
+    ticks = element_line(colour = "blue"),
+    ticks.length = unit(-5, "mm"),
+    # Adapt margins to accommodate longer ticks
+    text = element_text(margin = margin(l = 6, unit = "mm")),
+    margin = margin(l = 6, unit = "mm")
+  )
+
+ + +
+ +A trick you can pull to have legends eat up all the available real estate, is to give them `"null"`-unit size. Below, that trick stretches the colourbar across the full width of the plot. + +
+ +
p +
+  guides(colour = guide_colourbar(
+    theme = theme_sub_legend(
+      key.width = unit(1, "null"),
+      title.position = "top",
+      margin = margin_auto(NA, 0) # remove left/right margins
+    ),
+    position = "bottom"
+  ))
+
+ + +
+ +#### Binned legend + +A binned legend acts as a hybrid between a typical legend guide and a colourbar. It depicts a discretised continuous (binned) legend, by properly displaying separate glyphs, but also displaying an axis with ticks at bin breaks. + +
+ +
p +
+  guides(colour = "bins") +
+  theme_sub_legend(
+    axis.line = element_line("red"),
+    ticks = element_line("blue")
+  )
+
+ + +
+ +### Layers + +Since recently we can also set default choices for layer aesthetics via the theme. We briefly saw this foreshadowed in the 'tweaking complete themes' section. But you can have more granular control over layers as well, without affecting the entirety of the theme. + +#### Introducing the 'geom' element + +The new theme element powering all this is the `geom` argument. It takes the return value of the [`element_geom()`](https://ggplot2.tidyverse.org/reference/element.html) function to control the default graphical properties of layers. + +
+ +
p + 
+  # Turn off grouping
+  aes(colour = NULL, shape = NULL) +
+  geom_smooth(formula = y ~ x, method = "lm") +
+  theme(
+    geom = element_geom(
+      ink = "tomato",
+      paper = "dodgerblue",
+      accent = "forestgreen"
+    )
+  )
+
+ + +
+ +The [`element_geom()`](https://ggplot2.tidyverse.org/reference/element.html) function has a number of properties that we're about to describe. Just like other `element_*()` function, it returns an object with properties, most of which are `NULL` by default. These `NULL` properties will get filled in when the plot is built. + +
+ +
element_geom()
+#> <ggplot2::element_geom>
+#>  @ ink        : NULL
+#>  @ paper      : NULL
+#>  @ accent     : NULL
+#>  @ linewidth  : NULL
+#>  @ borderwidth: NULL
+#>  @ linetype   : NULL
+#>  @ bordertype : NULL
+#>  @ family     : NULL
+#>  @ fontsize   : NULL
+#>  @ pointsize  : NULL
+#>  @ pointshape : NULL
+#>  @ colour     : NULL
+#>  @ fill       : NULL
+
+ +
+ +##### Colours + +There are 5 colour related settings. In the plot above, we've already met three of them. + +- `ink` is the foreground colour. +- `paper` is the background colour. It is often used in a mixture with `ink` to dull the foreground and coordinate with the rest of the theme. You can see for example that the ribbon part of [`geom_smooth()`](https://ggplot2.tidyverse.org/reference/geom_smooth.html) is a bit purple-ish due to the mixture of reddish `ink` and bluish `paper`. +- `accent` is a speciality colour pick that only a few geoms use as default. These are [`geom_contour()`](https://ggplot2.tidyverse.org/reference/geom_contour.html), [`geom_quantile()`](https://ggplot2.tidyverse.org/reference/geom_quantile.html) and [`geom_smooth()`](https://ggplot2.tidyverse.org/reference/geom_smooth.html). + +The remaining two are well known to anyone who has worked with ggplot2 before: `colour` and `fill`. These two overrule any `ink`/`paper`/`accent` setting to directly set colour and fill without any mixing. For example, notice that the ribbon is a (semitransparent) purple, rather than a mixture with green paper. + +
+ +
last_plot() +
+  theme(geom = element_geom(
+    fill = "purple",
+    colour = "orange",
+    paper = "green" # Ignored
+  ))
+
+ + +
+ +##### Lines + +There are also 4 different line settings. You may already be familiar with `linewidth` and `linetype` setting how wide lines are, and how they are drawn respectively. Additionally, we're now also using `borderwidth` and `bordertype` to denote these settings for closed shapes that can be filled, like the rectangles below. + +
+ +
ggplot(faithful, aes(eruptions)) +
+  geom_histogram(aes(y = after_stat(density)), bins = 30, colour = "black") +
+  geom_line(stat = "density") +
+  theme(
+    geom = element_geom(
+      # Applies to the bars
+      borderwidth = 0.5,
+      bordertype = "dashed",
+      # Applies to the line
+      linewidth = 4,
+      linetype = "solid"
+    )
+  )
+
+ + +
+ +##### Points and text + +The four remaining settings pertains to text and points. Respectively `fontsize` and `pointsize` control the size. `pointshape` and `family` control the shape and font family. + +
+ +
ggplot(mtcars, aes(mpg, disp, label = rownames(mtcars))) +
+  geom_point() +
+  geom_label(nudge_x = 0.25, hjust = 0) +
+  theme(
+    geom = element_geom(
+      # Point settings
+      pointsize = 8,
+      pointshape = "←",
+      
+      # Text settings
+      fontsize = 8,
+      family = "Ink Free"
+    )
+  )
+
+ + +
+ +##### Micro-managing layers + +Aside from globally affecting every layer via `theme(geom)`, you can also fine-tune the appearance of individual geometry types. Whereas we envision `element_geom(ink, paper)` as the global 'aura' of a plot, the `element_geom(colour, fill)` is intended for tailoring specific geom types. We can add theme elements for specific geoms by replacing the snake_case layer function name by dot.case argument name. This works for layers that have an equivalent Geom ggproto class, which is the case for all geoms in ggplot2. + +
+ +
ggplot(mpg, aes(class, displ)) +
+  geom_boxplot(outliers = FALSE) +
+  geom_jitter() +
+  theme(
+    geom.point   = element_geom(colour = "dodgerblue"),
+    geom.boxplot = element_geom(fill = "orchid", colour = "turquoise")
+  )
+
+ + +
+ +##### Macro-managing layers + +There are now various options for how to change non-data parts of layers, and it can be a bit tricky to determine when you should use what option. Essentially, this is a 2-by-2 table covering the option of which layers to set (single, all) and when it is used (local, global). + +- If you want to change the look of a single layer in a single plot, you can just use the static (unmapped) aesthetics in a layer. For example: `geom_point(colour = "blue")`. + +- If you want to change the look of a single layer in all plots, you can use [`update_theme()`](https://ggplot2.tidyverse.org/reference/get_theme.html) to globally set a new (micro-managed) option. For example: `update_theme(geom.point = element_geom(colour = "blue"))`. You can also use the `element_geom(ink, paper)` settings but for single layers it may be more direct to use `element_geom(colour, fill)` instead. We no longer recommend, and even discourage (!) using [`update_geom_defaults()`](https://ggplot2.tidyverse.org/reference/update_defaults.html) for this purpose. + +- If you want to change the look of all layers in a single plot, you can use the `theme(geom)` argument and add it to a plot. For example: `theme(geom = element_geom(ink = "blue"))`. + +- If you want to change the look of all layers in all plots, you can also use [`update_theme()`](https://ggplot2.tidyverse.org/reference/get_theme.html) to globally set the `geom` option. For example: `update_theme(geom = element_geom(ink = "blue"))`. Alternatively, you can also coordinate the entire theme by using for example `set_theme(theme_gray(ink = "blue"))`. + +##### Access from layers + +Up to now, we've mostly described how to use the theme to instruct layers, but we can also instruct layers to lookup things from the theme too. Using the [`from_theme()`](https://ggplot2.tidyverse.org/reference/aes_eval.html) function in aesthetics allows you to use expressions with the variables present in [`element_geom()`](https://ggplot2.tidyverse.org/reference/element.html). For example, if you want to use a darker variant of the `accent` colour instead of `ink`, you might want to write your mapping as follows: + +
+ +
p + aes(colour = from_theme(scales::col_darker(accent, 20)))
+
+ + +
+ +#### Palettes + +In addition to controlling the default aesthetics from the theme, you can also control the default palettes from the theme. The palette theme settings all follow the following pattern, separated by dots: `palette`, aesthetic, type. The `type` can be either `continuous` or `discrete`. If you're using the default binned scale, it takes the continuous palette. For example, if we want to change the default `shape` and `colour` palettes, we can declare that as follows: + +
+ +
p + theme(
+  palette.shape.discrete = c("plus", "triangle", "diamond"),
+  palette.colour.continuous = c("maroon", "hotpink", "white")
+)
+
+ + +
+ +The values of these palette theme elements are passed down to [`scales::as_discrete_pal()`](https://scales.r-lib.org/reference/new_continuous_palette.html) and [`scales::as_continuous_pal()`](https://scales.r-lib.org/reference/new_continuous_palette.html) for discrete and continuous scales respectively. + +### Theme elements in extensions + +Aside from extensions providing whole, complete themes, extensions may also define new theme elements. You can sometimes see these in facets, coords or guide extensions. With these wide use-cases, we cannot really describe these as much as just acknowledge they exist. For example, the ggforce package has a zoom element that controls the appearance of zooming indicators. + +
+ +
p + ggforce::facet_zoom(ylim = c(20, 30), xlim = c(3, 4)) +
+  theme(zoom = element_rect(colour = "red", linewidth = 0.2, fill = NA))
+
+ + +
+ +If you are writing your own extension and need to compute a bespoke element from the theme, you can use [`register_theme_elements()`](https://ggplot2.tidyverse.org/reference/register_theme_elements.html) to ensure ggplot2 knows about your element and can use it in [`calc_element()`](https://ggplot2.tidyverse.org/reference/calc_element.html). + +
+ +
# A custom element comes up empty
+calc_element("my_element", complete_theme())
+#> NULL
+
+# Register element
+register_theme_elements(
+  my_element = element_rect(),
+  element_tree = list(
+    my_element = el_def(
+      class = "element_rect", # Must be a rect element
+      inherit = "rect" # Get settings from theme(rect)
+    )
+  )
+)
+
+# Now custom element can be computed
+calc_element("my_element", complete_theme())
+#> <ggplot2::element_rect>
+#>  @ fill         : chr "white"
+#>  @ colour       : chr "black"
+#>  @ linewidth    : num 0.5
+#>  @ linetype     : num 1
+#>  @ linejoin     : chr "round"
+#>  @ inherit.blank: logi TRUE
+
+ +
+ +## Writing your own theme + +When you are writing your own theme there are a few things to keep in mind. A guiding principle is to write your themes such that it is robust to upstream changes. Not only can ggplot2 add, deprecate or reroute elements, also theme elements used by extensions should be accommodated. + +#### 1. Use a function + +First, this principle means that you should write your theme as a function. Writing your theme as a function ensures it can be rebuild. This is opposed to assigning a theme object to a variable in your package's namespace ---or heaven forbid--- save it as a file, If you assign your theme object to a variable in your namespace, the object will get compiled into your code and can cause build time warnings or errors if an element function or argument get updated. + +
+ +
my_theme <- function(...) {}
+ +
+ +#### 2. Use a base theme + +Secondly, it is good practise to start your own theme as a function that calls a complete theme function as its base. It ensures that when ggplot2 adds new elements that belong in complete themes, your theme also remains complete. + +
+ +
my_theme <- function(...) {
+  theme_gray(...)
+}
+ +
+ +### 3. Use `theme()` to add elements + +Third, you should use [`theme()`](https://ggplot2.tidyverse.org/reference/theme.html) to add new elements to the base. While it is technically possible to assign additional elements by sub-assignment (`$<-`), we strong advice against this. Using [`theme()`](https://ggplot2.tidyverse.org/reference/theme.html) ensures that any deprecated arguments are redirected to an appropriate place. + +
+ +
# Do *not* do the following!
+my_fragile_theme <- function(...) {
+  t <- theme_gray(...)
+  t$legend.text <- element_text() # BAD
+  t
+}
+ +
+ +You can use `+ theme()` or `%+replace% theme()`, where `+` merges elements and `%+replace%` replaces elements by completely removing old settings. If you use `%+replace%` for a root element, like `text` or `line`, you should take care that every property has non-null values. + +
+ +
my_theme <- function(...) {
+  theme_gray(...) %+replace%
+    theme(
+      # Because we're replacing, we should fully define root elements
+      text = element_text(
+        family = "", face = "plain", colour = "red", size = 11, 
+        hjust = 0.5, vjust = 0.5, angle = 0, lineheight = 1, margin = margin()
+      ),
+      # Non-root elements can be partially defined
+      legend.text = element_text(colour = "blue")
+    ) +
+    # Here we're updating the root line element with `+`, instead of replacing it
+    theme(line = element_line(linetype = "dotted"))
+}
+
+p + my_theme()
+
+ + +
+ +#### 4. Caching themes + +We mentioned in 1. that you shouldn't assign a theme object to a variable in your namespace. However, you may want to reuse a theme without having to reconstruct it every time because you may never need to change arguments in your package. The solution we recommend for this use case, is to cache your theme when your package is loaded. It ensures that we observe all the formalities of building a theme, with all the protections this offers, but we need to do this only once per session. + +
+ +
# Create a variable for your future theme
+cached_theme <- NULL
+
+# In your .onLoad function, construct the theme
+.onLoad <- function(libname, pkgname) {
+  cached_theme <<- my_theme()
+}
+
+# In your package's functions, you can now use the cached theme
+my_plotting_function <- function() {
+  ggplot(mpg, aes(displ, hwy)) +
+    geom_point() +
+    cached_theme
+}
+
+# Simulate loading
+.onLoad()
+
+# Works!
+my_plotting_function()
+
+ + +
+ +## Tips and tricks + +### Global theme + +Are you also used to writing entire booklets of theme settings at every plot? Do your fingers tire of typing `panel.background = element_blank()` dozens of times in a script? Worry no more! Set your theme settings to permanent today by using the one-time offer of [`set_theme()`](https://ggplot2.tidyverse.org/reference/get_theme.html)! + +
+ +
my_theme <- function(...) {
+  theme_gray() +
+    theme(
+      panel.background = element_blank(),
+      panel.grid = element_line(colour = "grey95"),
+      palette.colour.continuous = "viridis"
+    )
+}
+
+set_theme(my_theme())
+
+# Global goodness galore!
+p
+
+ + +
+ +To undo any globally set theme, you can use [`reset_theme_settings()`](https://ggplot2.tidyverse.org/reference/register_theme_elements.html). + +### Fonts + +Setting the typography of your plots is important and discussed more thoroughly in [this blog post](https://www.tidyverse.org/blog/2025/05/fonts-in-r/). Here we're simply giving the suggestion to use the [`systemfonts::require_font()`](https://systemfonts.r-lib.org/reference/require_font.html) when you are writing theme functions that include special fonts. It will not cover font behaviour for every graphics device, but it will for devices that use [systemfonts](https://systemfonts.r-lib.org/) for finding fonts, like [ragg](https://ragg.r-lib.org/) and [svglite](https://svglite.r-lib.org/). + +
+ +
my_theme <- function(header_family = "Impact", ...) {
+  systemfonts::require_font(header_family)
+  theme_gray(header_family = header_family, ...)
+}
+
+p + my_theme()
+
+ + +
+ +### Bundling theme settings + +Not every theme needs to be a complete theme. You can write partial themes that bundle together related settings to achieve an effect you want. For example, here are some settings that left-aligns the title and legend at the top of a plot. + +
+ +
upper_legend <- function() {
+  theme(
+    plot.title.position = "plot",
+    legend.location = "plot",
+    legend.position = "top",
+    legend.justification.top = "left",
+    legend.title.position = "top",
+    legend.margin = margin_part(l = 0)
+  )
+}
+
+p +
+  aes(colour = NULL) +
+  upper_legend()
+
+ + +
+ +Another example for bottom placement of colour bars: + +
+ +
bottom_colourbar <- function() {
+  theme_sub_legend(
+    position = "bottom",
+    title.position = "top",
+    justification.bottom = "left",
+    # Stretch bar across width of panels
+    key.width = unit(1, "null"), 
+    margin = margin_part(l = 0, r = 0)
+  )
+}
+
+p + 
+  aes(shape = NULL) +
+  bottom_colourbar()
+
+ + +
+ +If you don't mind venturing outside the grammar for a brisk stroll, you can also bundle theme settings together with other components. For example, in a bar chart you may wish to suppress vertical grid lines and not expand the y-axis at the bottom. + +
+ +
barchart_settings <- function() {
+  list(
+    theme(panel.grid.major.x = element_blank()),
+    coord_cartesian(expand = c(bottom = FALSE))
+  )
+}
+
+ggplot(mpg, aes(class)) +
+  geom_bar() +
+  barchart_settings()
+
+ + +
+ +The point here is not to make an exhaustive list of all useful bundles, it is to highlight that it possible to create reusable chunks of theme. + +### Pattern rectangles + +Did you know that `element_rect(fill)` can be a grid pattern? You can use it to place images in the panel background, which can be neat for branding. + +
+ +
pattern <- "https://raw.githubusercontent.com/tidyverse/ggplot2/refs/heads/main/man/figures/logo.png" |> 
+  magick::image_read() |>
+  grid::rasterGrob(
+    x = 0.8, y = 0.8,
+    width = unit(0.2, "snpc"), 
+    height = unit(0.23, "snpc"), 
+  ) |>
+  grid::pattern(extend = "none")
+
+p + 
+  theme(
+    panel.background = element_rect(fill = pattern),
+    # legend.key inherits from panel background, so we tweak it
+    legend.key = element_blank(),
+    # make grid semitransparent to lay over pattern
+    panel.grid = element_line(colour = alpha("black", 0.05))
+  )
+
+ + +
+ +## Finally + +This article has been light on advice on how you should or should not use themes. Mostly, this is to encourage experimentation. Don't be afraid to put in a personal twist. Make mistakes. Discover why a theme does or doesn't work for a plot. If you cannot be bothered, there are [extension packages](https://exts.ggplot2.tidyverse.org/gallery/) that offer plenty of options. The [tidytuesday](https://github.com/rfordatascience/tidytuesday) project has spawned a rich source of varied plotting code, including themes people use. If you like a tidytuesday plot, find the source code and see how the sausage is made. Find whatever theme works for you and your plots. + diff --git a/content/blog/ggplot2-styling/save-svg-as-png-1.4.17/save-svg-as-png.min.js b/content/blog/ggplot2-styling/save-svg-as-png-1.4.17/save-svg-as-png.min.js new file mode 100644 index 000000000..181ce29a9 --- /dev/null +++ b/content/blog/ggplot2-styling/save-svg-as-png-1.4.17/save-svg-as-png.min.js @@ -0,0 +1 @@ +"use strict";!function(){function e(e){if(!l(e))throw new Error("an HTMLElement or SVGElement is required; got "+e)}function t(e){return new Promise((function(t,n){l(e)?t(e):n(new Error("an HTMLElement or SVGElement is required; got "+e))}))}function n(e){for(var t=window.atob(e.split(",")[1]),n=(e=e.split(",")[0].split(":")[1].split(";")[0],new ArrayBuffer(t.length)),r=new Uint8Array(n),o=0;o *")).forEach((function(e){e.setAttributeNS(i,"xmlns","svg"===e.tagName?a:"http://www.w3.org/1999/xhtml")})),v?((y=document.createElement("div")).appendChild(T),e=y.innerHTML,"function"!=typeof r?{src:e,width:k,height:L}:void r(e,k,L)):(o=t,s=(U=(U=n)||{}).selectorRemap,b=U.modifyStyle,O=U.modifyCss,y=U.fonts,x=U.excludeUnusedCss,A=O||function(e,t){return(s?s(e):e)+"{"+(b?b(t):t)+"}\n"},S=[],E=void 0===y,C=y||[],p().forEach((function(e){var t=e.rules,n=e.href;t&&Array.from(t).forEach((function(e){var t;void 0!==e.style&&(function(e,t){if(t)try{return e.querySelector(t)||e.parentNode&&e.parentNode.querySelector(t)}catch(e){console.warn('Invalid CSS selector "'+t+'"',e)}}(o,e.selectorText)?S.push(A(e.selectorText,e.style.cssText)):E&&e.cssText.match(/^@font-face/)?(t=f(e,n))&&C.push(t):x||S.push(e.cssText))}))})),w(C).then((function(e){return S.join("\n")+e})).then((function(e){var t;if((t=document.createElement("style")).setAttribute("type","text/css"),t.innerHTML="",((e=document.createElement("defs")).appendChild(t),T.insertBefore(e,T.firstChild),t=document.createElement("div")).appendChild(T),e=t.innerHTML.replace(/NS\d+:href/gi,'xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href'),"function"!=typeof r)return{src:e,width:k,height:L};r(e,k,L)})))}))},o.svgAsDataUri=function(t,n,r){return e(t),o.prepareSvg(t,n).then((function(e){var t=e.src,n=e.width;return e=e.height,t="data:image/svg+xml;base64,"+window.btoa(decodeURIComponent(encodeURIComponent(']>'+t).replace(/%([0-9A-F]{2})/g,(function(e,t){return"%"===(t=String.fromCharCode("0x"+t))?"%25":t})))),"function"==typeof r&&r(t,n,e),t}))},o.svgAsPngUri=function(t,n,r){function i(e){var t=e.src,n=e.width,o=(e=e.height,document.createElement("canvas")),i=o.getContext("2d"),a=window.devicePixelRatio||1;o.width=n*a,o.height=e*a,o.style.width=o.width+"px",o.style.height=o.height+"px",i.setTransform(a,0,0,a,0,0),n=void(c?c(o,t):i.drawImage(t,0,0));try{n=o.toDataURL(u,l)}catch(e){if("undefined"!=typeof SecurityError&&e instanceof SecurityError||"SecurityError"===e.name)return void console.error("Rendered SVG images cannot be downloaded in this browser.");throw e}return"function"==typeof r&&r(n,o.width,o.height),Promise.resolve(n)}e(t);var a,s=n||{},u=void 0===(a=s.encoderType)?"image/png":a,l=void 0===(a=s.encoderOptions)?.8:a,c=s.canvg;return c?o.prepareSvg(t,n).then(i):o.svgAsDataUri(t,n).then((function(e){return new Promise((function(t,n){var r=new Image;r.onload=function(){return t(i({src:r,width:r.width,height:r.height}))},r.onerror=function(){n("There was an error loading the data URI as an image on the following SVG\n"+window.atob(e.slice(26))+"Open the following link to see browser's diagnosis\n"+e)},r.src=e}))}))},o.download=function(e,t,r){if(navigator.msSaveOrOpenBlob)navigator.msSaveOrOpenBlob(n(t),e);else{var o=document.createElement("a");if("download"in o){o.download=e,o.style.display="none",document.body.appendChild(o);try{var i=n(t),a=URL.createObjectURL(i);o.href=a,o.onclick=function(){return requestAnimationFrame((function(){return URL.revokeObjectURL(a)}))}}catch(e){console.error(e),console.warn("Error while getting object URL. Falling back to string URL."),o.href=t}o.click(),document.body.removeChild(o)}else r&&r.popup&&(r.popup.document.title=e,r.popup.location.replace(t))}},o.saveSvg=function(e,n,i){var a=r();return t(e).then((function(e){return o.svgAsDataUri(e,i||{})})).then((function(e){return o.download(n,e,a)}))},o.saveSvgAsPng=function(e,n,i){var a=r();return t(e).then((function(e){return o.svgAsPngUri(e,i||{})})).then((function(e){return o.download(n,e,a)}))}}(); \ No newline at end of file diff --git a/content/blog/ggplot2-styling/thumbnail-sq.jpg b/content/blog/ggplot2-styling/thumbnail-sq.jpg new file mode 100644 index 000000000..a75d0f796 Binary files /dev/null and b/content/blog/ggplot2-styling/thumbnail-sq.jpg differ diff --git a/content/blog/ggplot2-styling/thumbnail-wd.jpg b/content/blog/ggplot2-styling/thumbnail-wd.jpg new file mode 100644 index 000000000..c3af0d6e9 Binary files /dev/null and b/content/blog/ggplot2-styling/thumbnail-wd.jpg differ diff --git a/themes/hugo-graphite/layouts/_default/baseof.html b/themes/hugo-graphite/layouts/_default/baseof.html index 3afc612d0..b0118c193 100644 --- a/themes/hugo-graphite/layouts/_default/baseof.html +++ b/themes/hugo-graphite/layouts/_default/baseof.html @@ -2,6 +2,9 @@ {{ partial "header.html" . }} +{{ range .Params.html_dependencies }} + {{ . | safeHTML }} +{{ end }}