Repository: facelessuser/coloraide (language: python)

Issue:
XYB Color Space
LMS based color space used in JPEG XL

https://ds.jpeg.org/whitepapers/jpeg-xl-whitepaper.pdf


Discussion / hints:

Fix patch:
diff --git a/coloraide/everything.py b/coloraide/everything.py
index 9bc1f54cb..2d6b2a179 100644
--- a/coloraide/everything.py
+++ b/coloraide/everything.py
@@ -20,6 +20,7 @@
 from .spaces.cmy import CMY
 from .spaces.cmyk import CMYK
 from .spaces.xyy import xyY
+from .spaces.xyb import XYB
 from .spaces.hunter_lab import HunterLab
 from .spaces.prismatic import Prismatic
 from .spaces.rlab import RLAB
@@ -74,6 +75,7 @@ class ColorAll(Base):
         CMY(),
         CMYK(),
         xyY(),
+        XYB(),
         HunterLab(),
         Prismatic(),
         RLAB(),
diff --git a/coloraide/spaces/xyb.py b/coloraide/spaces/xyb.py
new file mode 100644
index 000000000..f9e013db4
--- /dev/null
+++ b/coloraide/spaces/xyb.py
@@ -0,0 +1,99 @@
+"""
+XYB color space.
+
+https://ds.jpeg.org/whitepapers/jpeg-xl-whitepaper.pdf
+"""
+from __future__ import annotations
+from .. import algebra as alg
+from ..spaces import Space, Labish
+from ..types import Vector
+from ..cat import WHITES
+from ..channels import Channel, FLG_MIRROR_PERCENT
+
+BIAS = 0.00379307325527544933
+BIAS_CBRT = alg.nth_root(BIAS, 3)
+
+LRGB_TO_LMS = [
+    [0.3, 0.622, 0.078],
+    [0.23, 0.692, 0.078],
+    [0.24342268924547819, 0.20476744424496821, 0.55180986650955360]
+]
+
+LMS_TO_LRGB = [
+    [11.031566904639865, -9.866943908131564, -0.16462299650829934],
+    [-3.254147381074425, 4.4187703775827245, -0.16462299650829929],
+    [-3.6588512867136815, 2.712923045936092, 1.945928240777589]
+]
+
+# https://twitter.com/jonsneyers/status/1605321352143331328
+# @jonsneyers Feb 22
+# Yes, the default is to just subtract Y from B. In general there are locally
+# signaled float multipliers to subtract some multiple of Y from X and some
+# other multiple from B. But this is the baseline, making X=B=0 grayscale.
+# ----
+# We adjust the matrix to subtract Y from B match this statement.
+XYB_LMS_TO_XYB = [
+    [0.5, -0.5, 0.0],
+    [0.5, 0.5, 0.0],
+    [0.0, -1.0, 1.0],
+]
+
+XYB_TO_XYB_LMS = [
+    [1.0, 1.0, 0.0],
+    [-1.0, 1.0, 0.0],
+    [-1.0, 1.0, 1.0]
+]
+
+
+def rgb_to_xyb(rgb: Vector) -> Vector:
+    """Linear sRGB to XYB."""
+
+    return alg.dot(
+        XYB_LMS_TO_XYB,
+        [alg.nth_root(c + BIAS, 3) - BIAS_CBRT for c in alg.dot(LRGB_TO_LMS, rgb, dims=alg.D2_D1)],
+        dims=alg.D2_D1
+    )
+
+
+def xyb_to_rgb(xyb: Vector) -> Vector:
+    """XYB to linear sRGB."""
+
+    # This cleans up the round trip on black.
+    if not any(xyb):
+        return [0.0] * 3
+
+    return alg.dot(
+        LMS_TO_LRGB,
+        [(c + BIAS_CBRT) ** 3 - BIAS for c in alg.dot(XYB_TO_XYB_LMS, xyb, dims=alg.D2_D1)],
+        dims=alg.D2_D1
+    )
+
+
+class XYB(Labish, Space):
+    """XYB color class."""
+
+    BASE = 'srgb-linear'
+    NAME = "xyb"
+    SERIALIZE = ("--xyb",)
+    WHITE = WHITES['2deg']['D65']
+    CHANNELS = (
+        Channel("x", -0.45, 0.45, flags=FLG_MIRROR_PERCENT),
+        Channel("y", 0.0, 0.845),
+        Channel("b", -0.45, 0.45, flags=FLG_MIRROR_PERCENT)
+    )
+
+    def names(self) -> tuple[str, ...]:
+        """Return Lab-ish names in the order L a b."""
+
+        channels = self.channels
+        return channels[1], channels[0], channels[2]
+
+    def to_base(self, coords: Vector) -> Vector:
+        """To XYB from base."""
+
+        return xyb_to_rgb(coords)
+
+    def from_base(self, coords: Vector) -> Vector:
+        """From base to XYB."""
+
+        return rgb_to_xyb(coords)
diff --git a/docs/src/dictionary/en-custom.txt b/docs/src/dictionary/en-custom.txt
index 3ad9aa9db..be015dcf5 100644
--- a/docs/src/dictionary/en-custom.txt
+++ b/docs/src/dictionary/en-custom.txt
@@ -179,6 +179,7 @@ Vos
 WCAG
 WCG
 XD
+XYB
 XYZ
 YCbCr
 ZD
@@ -229,6 +230,7 @@ io
 ish
 iterable
 ixora
+jonsneyers
 js
 jz
 luma
diff --git a/docs/src/markdown/about/changelog.md b/docs/src/markdown/about/changelog.md
index 5cc4bc041..2d2ef4bb5 100644
--- a/docs/src/markdown/about/changelog.md
+++ b/docs/src/markdown/about/changelog.md
@@ -1,5 +1,9 @@
 # Changelog
 
+## Next
+
+- **NEW**: Add XYB color space.
+
 ## 2.1
 
 - **NEW**: Add new color averaging method.
diff --git a/docs/src/markdown/colors/index.md b/docs/src/markdown/colors/index.md
index 363ca9dee..e050dadcb 100644
--- a/docs/src/markdown/colors/index.md
+++ b/docs/src/markdown/colors/index.md
@@ -58,6 +58,7 @@ flowchart TB
         hsi --- srgb
         cmy --- srgb
         cmyk --- srgb
+        xyb --- srgb
 
     rec2020 --- rec2020-linear --- xyz-d65
         rec2100-pq --- rec2020-linear
@@ -149,6 +150,7 @@ flowchart TB
     cam16-scd(CAM16 SCD)
     cam16-lcd(CAM16 LCD)
     hct(HCT)
+    xyb(XYB)
 
     click xyz-d65 "./xyz_d65/" _self
     click xyz-d50 "./xyz_d50/" _self
@@ -204,5 +206,6 @@ flowchart TB
     click cam16-scd "./cam16_scd/" _self
     click cam16-lcd "./cam16_lcd/" _self
     click hct "./hct/" _self
+    click xyb "./xyb/" _self
 ```
 ///
diff --git a/docs/src/markdown/colors/xyb.md b/docs/src/markdown/colors/xyb.md
new file mode 100644
index 000000000..1b84d7edb
--- /dev/null
+++ b/docs/src/markdown/colors/xyb.md
@@ -0,0 +1,80 @@
+# XYB
+
+/// failure | The XYB color space is not registered in `Color` by default
+///
+
+/// html | div.info-container
+//// info | Properties
+    attrs: {class: inline end}
+
+**Name:** `xyb`
+
+**White Point:** D65
+
+**Coordinates:**
+
+Name | Range^\*^
+---- | -----
+`x`  | [-0.45, 0.45]
+`y`  | [0.0, 0.845]
+`b`  | [-0.45, 0.45]
+
+^\*^ Space is not bound to the range and is only used as a reference to define percentage inputs/outputs.
+////
+
+//// html | figure
+![XYB](../images/xyb-3d.png)
+
+///// html | figcaption
+The sRGB gamut represented within the XYB color space.
+/////
+////
+
+XYB is a color space that was designed for use with the JPEG XL Image Coding System. It is an LMS-based color model
+inspired by the human visual system, facilitating perceptually uniform quantization. It uses a gamma of 3 for
+computationally efficient decoding.
+
+//// tip | Chroma/Luma Adjustments
+Per the creator, the default subtracts the Y component from the B component which makes Y function as lightness and X
+and Y like Lab a and b. When X=Y=0, the color is achromatic. You may find other implementations do not do this only
+because it is not documented well.
+////
+
+[Learn more](https://ds.jpeg.org/whitepapers/jpeg-xl-whitepaper.pdf).
+///
+
+## Channel Aliases
+
+Channels | Aliases
+-------- | -------
+`x`      |
+`y`      |
+`b`      |
+
+**Inputs**
+
+The XYB space is not currently supported in the CSS spec, the parsed input and string output formats use the
+`#!css-color color()` function format using the custom name `#!css-color --xyb`:
+
+```css-color
+color(--xyb x y b / a)  // Color function
+```
+
+The string representation of the color object and the default string output use the
+`#!css-color color(--xyb x y b / a)` form.
+
+```py play
+Color("xyb", [0.0281, 0.48819, 0.01157])
+Color("xyb", [0.01132, 0.64596, -0.10359]).to_string()
+```
+
+## Registering
+
+```py
+from coloraide import Color as Base
+from coloraide.spaces.xyb import XYB
+
+class Color(Base): ...
+
+Color.register(XYB())
+```
diff --git a/docs/src/markdown/images/xyb-3d.png b/docs/src/markdown/images/xyb-3d.png
new file mode 100644
index 000000000..95763a6ca
Binary files /dev/null and b/docs/src/markdown/images/xyb-3d.png differ
diff --git a/docs/src/mkdocs.yml b/docs/src/mkdocs.yml
index 262fc560f..c10ca5fb0 100644
--- a/docs/src/mkdocs.yml
+++ b/docs/src/mkdocs.yml
@@ -98,6 +98,7 @@ nav:
         - CAM16 UCS: colors/cam16_ucs.md
         - CAM16 SCD: colors/cam16_scd.md
         - CAM16 LCD: colors/cam16_lcd.md
+        - XYB: colors/xyb.md
 
       - LCh Like Spaces:
         - LCh D50: colors/lch.md
diff --git a/docs/theme/assets/coloraide-extras/extra-notebook-3d99782d.js b/docs/theme/assets/coloraide-extras/extra-notebook-b5858b87.js
similarity index 57%
rename from docs/theme/assets/coloraide-extras/extra-notebook-3d99782d.js
rename to docs/theme/assets/coloraide-extras/extra-notebook-b5858b87.js
index ae1314843..4f5874443 100644
--- a/docs/theme/assets/coloraide-extras/extra-notebook-3d99782d.js
+++ b/docs/theme/assets/coloraide-extras/extra-notebook-b5858b87.js
@@ -1,2 +1,2 @@
-function _typeof(t){return _typeof="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},_typeof(t)}var runtime=function(t){"use strict";var e,n=Object.prototype,o=n.hasOwnProperty,r=Object.defineProperty||function(t,e,n){t[e]=n.value},a="function"==typeof Symbol?Symbol:{},i=a.iterator||"@@iterator",s=a.asyncIterator||"@@asyncIterator",l=a.toStringTag||"@@toStringTag";function c(t,e,n){return Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{c({},"")}catch(t){c=function(t,e,n){return t[e]=n}}function u(t,e,n,o){var a=e&&e.prototype instanceof _?e:_,i=Object.create(a.prototype),s=new I(o||[]);return r(i,"_invoke",{value:S(t,n,s)}),i}function d(t,e,n){try{return{type:"normal",arg:t.call(e,n)}}catch(t){return{type:"throw",arg:t}}}t.wrap=u;var p="suspendedStart",f="suspendedYield",m="executing",g="completed",h={};function _(){}function y(){}function v(){}var w={};c(w,i,(function(){return this}));var x=Object.getPrototypeOf,b=x&&x(x(T([])));b&&b!==n&&o.call(b,i)&&(w=b);var E=v.prototype=_.prototype=Object.create(w);function k(t){["next","throw","return"].forEach((function(e){c(t,e,(function(t){return this._invoke(e,t)}))}))}function L(t,e){function n(r,a,i,s){var l=d(t[r],t,a);if("throw"!==l.type){var c=l.arg,u=c.value;return u&&"object"===_typeof(u)&&o.call(u,"__await")?e.resolve(u.__await).then((function(t){n("next",t,i,s)}),(function(t){n("throw",t,i,s)})):e.resolve(u).then((function(t){c.value=t,i(c)}),(function(t){return n("throw",t,i,s)}))}s(l.arg)}var a;r(this,"_invoke",{value:function(t,o){function r(){return new e((function(e,r){n(t,o,e,r)}))}return a=a?a.then(r,r):r()}})}function S(t,e,n){var o=p;return function(r,a){if(o===m)throw new Error("Generator is already running");if(o===g){if("throw"===r)throw a;return O()}for(n.method=r,n.arg=a;;){var i=n.delegate;if(i){var s=A(i,n);if(s){if(s===h)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(o===p)throw o=g,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o=m;var l=d(t,e,n);if("normal"===l.type){if(o=n.done?g:f,l.arg===h)continue;return{value:l.arg,done:n.done}}"throw"===l.type&&(o=g,n.method="throw",n.arg=l.arg)}}}function A(t,n){var o=n.method,r=t.iterator[o];if(r===e)return n.delegate=null,"throw"===o&&t.iterator.return&&(n.method="return",n.arg=e,A(t,n),"throw"===n.method)||"return"!==o&&(n.method="throw",n.arg=new TypeError("The iterator does not provide a '"+o+"' method")),h;var a=d(r,t.iterator,n.arg);if("throw"===a.type)return n.method="throw",n.arg=a.arg,n.delegate=null,h;var i=a.arg;return i?i.done?(n[t.resultName]=i.value,n.next=t.nextLoc,"return"!==n.method&&(n.method="next",n.arg=e),n.delegate=null,h):i:(n.method="throw",n.arg=new TypeError("iterator result is not an object"),n.delegate=null,h)}function C(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function B(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function I(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(C,this),this.reset(!0)}function T(t){if(t){var n=t[i];if(n)return n.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var r=-1,a=function n(){for(;++r<t.length;)if(o.call(t,r))return n.value=t[r],n.done=!1,n;return n.value=e,n.done=!0,n};return a.next=a}}return{next:O}}function O(){return{value:e,done:!0}}return y.prototype=v,r(E,"constructor",{value:v,configurable:!0}),r(v,"constructor",{value:y,configurable:!0}),y.displayName=c(v,l,"GeneratorFunction"),t.isGeneratorFunction=function(t){var e="function"==typeof t&&t.constructor;return!!e&&(e===y||"GeneratorFunction"===(e.displayName||e.name))},t.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,v):(t.__proto__=v,c(t,l,"GeneratorFunction")),t.prototype=Object.create(E),t},t.awrap=function(t){return{__await:t}},k(L.prototype),c(L.prototype,s,(function(){return this})),t.AsyncIterator=L,t.async=function(e,n,o,r,a){void 0===a&&(a=Promise);var i=new L(u(e,n,o,r),a);return t.isGeneratorFunction(n)?i:i.next().then((function(t){return t.done?t.value:i.next()}))},k(E),c(E,l,"Generator"),c(E,i,(function(){return this})),c(E,"toString",(function(){return"[object Generator]"})),t.keys=function(t){var e=Object(t),n=[];for(var o in e)n.push(o);return n.reverse(),function t(){for(;n.length;){var o=n.pop();if(o in e)return t.value=o,t.done=!1,t}return t.done=!0,t}},t.values=T,I.prototype={constructor:I,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=e,this.done=!1,this.delegate=null,this.method="next",this.arg=e,this.tryEntries.forEach(B),!t)for(var n in this)"t"===n.charAt(0)&&o.call(this,n)&&!isNaN(+n.slice(1))&&(this[n]=e)},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var n=this;function r(o,r){return s.type="throw",s.arg=t,n.next=o,r&&(n.method="next",n.arg=e),!!r}for(var a=this.tryEntries.length-1;a>=0;--a){var i=this.tryEntries[a],s=i.completion;if("root"===i.tryLoc)return r("end");if(i.tryLoc<=this.prev){var l=o.call(i,"catchLoc"),c=o.call(i,"finallyLoc");if(l&&c){if(this.prev<i.catchLoc)return r(i.catchLoc,!0);if(this.prev<i.finallyLoc)return r(i.finallyLoc)}else if(l){if(this.prev<i.catchLoc)return r(i.catchLoc,!0)}else{if(!c)throw new Error("try statement without catch or finally");if(this.prev<i.finallyLoc)return r(i.finallyLoc)}}}},abrupt:function(t,e){for(var n=this.tryEntries.length-1;n>=0;--n){var r=this.tryEntries[n];if(r.tryLoc<=this.prev&&o.call(r,"finallyLoc")&&this.prev<r.finallyLoc){var a=r;break}}a&&("break"===t||"continue"===t)&&a.tryLoc<=e&&e<=a.finallyLoc&&(a=null);var i=a?a.completion:{};return i.type=t,i.arg=e,a?(this.method="next",this.next=a.finallyLoc,h):this.complete(i)},complete:function(t,e){if("throw"===t.type)throw t.arg;return"break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&e&&(this.next=e),h},finish:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.finallyLoc===t)return this.complete(n.completion,n.afterLoc),B(n),h}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc===t){var o=n.completion;if("throw"===o.type){var r=o.arg;B(n)}return r}}throw new Error("illegal catch attempt")},delegateYield:function(t,n,o){return this.delegate={iterator:T(t),resultName:n,nextLoc:o},"next"===this.method&&(this.arg=e),h}},t}("object"===("undefined"==typeof module?"undefined":_typeof(module))?module.exports:{});try{regeneratorRuntime=runtime}catch(t){"object"===("undefined"==typeof globalThis?"undefined":_typeof(globalThis))?globalThis.regeneratorRuntime=runtime:Function("r","regeneratorRuntime = r")(runtime)}!function(){"use strict";function t(){t=function(){return e};var e={},n=Object.prototype,o=n.hasOwnProperty,r=Object.defineProperty||function(t,e,n){t[e]=n.value},a="function"==typeof Symbol?Symbol:{},i=a.iterator||"@@iterator",s=a.asyncIterator||"@@asyncIterator",l=a.toStringTag||"@@toStringTag";function c(t,e,n){return Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{c({},"")}catch(t){c=function(t,e,n){return t[e]=n}}function u(t,e,n,o){var a=e&&e.prototype instanceof f?e:f,i=Object.create(a.prototype),s=new S(o||[]);return r(i,"_invoke",{value:b(t,n,s)}),i}function d(t,e,n){try{return{type:"normal",arg:t.call(e,n)}}catch(t){return{type:"throw",arg:t}}}e.wrap=u;var p={};function f(){}function m(){}function g(){}var h={};c(h,i,(function(){return this}));var _=Object.getPrototypeOf,y=_&&_(_(A([])));y&&y!==n&&o.call(y,i)&&(h=y);var v=g.prototype=f.prototype=Object.create(h);function w(t){["next","throw","return"].forEach((function(e){c(t,e,(function(t){return this._invoke(e,t)}))}))}function x(t,e){function n(r,a,i,s){var l=d(t[r],t,a);if("throw"!==l.type){var c=l.arg,u=c.value;return u&&"object"==_typeof(u)&&o.call(u,"__await")?e.resolve(u.__await).then((function(t){n("next",t,i,s)}),(function(t){n("throw",t,i,s)})):e.resolve(u).then((function(t){c.value=t,i(c)}),(function(t){return n("throw",t,i,s)}))}s(l.arg)}var a;r(this,"_invoke",{value:function(t,o){function r(){return new e((function(e,r){n(t,o,e,r)}))}return a=a?a.then(r,r):r()}})}function b(t,e,n){var o="suspendedStart";return function(r,a){if("executing"===o)throw new Error("Generator is already running");if("completed"===o){if("throw"===r)throw a;return C()}for(n.method=r,n.arg=a;;){var i=n.delegate;if(i){var s=E(i,n);if(s){if(s===p)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if("suspendedStart"===o)throw o="completed",n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o="executing";var l=d(t,e,n);if("normal"===l.type){if(o=n.done?"completed":"suspendedYield",l.arg===p)continue;return{value:l.arg,done:n.done}}"throw"===l.type&&(o="completed",n.method="throw",n.arg=l.arg)}}}function E(t,e){var n=e.method,o=t.iterator[n];if(void 0===o)return e.delegate=null,"throw"===n&&t.iterator.return&&(e.method="return",e.arg=void 0,E(t,e),"throw"===e.method)||"return"!==n&&(e.method="throw",e.arg=new TypeError("The iterator does not provide a '"+n+"' method")),p;var r=d(o,t.iterator,e.arg);if("throw"===r.type)return e.method="throw",e.arg=r.arg,e.delegate=null,p;var a=r.arg;return a?a.done?(e[t.resultName]=a.value,e.next=t.nextLoc,"return"!==e.method&&(e.method="next",e.arg=void 0),e.delegate=null,p):a:(e.method="throw",e.arg=new TypeError("iterator result is not an object"),e.delegate=null,p)}function k(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function L(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function S(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(k,this),this.reset(!0)}function A(t){if(t){var e=t[i];if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var n=-1,r=function e(){for(;++n<t.length;)if(o.call(t,n))return e.value=t[n],e.done=!1,e;return e.value=void 0,e.done=!0,e};return r.next=r}}return{next:C}}function C(){return{value:void 0,done:!0}}return m.prototype=g,r(v,"constructor",{value:g,configurable:!0}),r(g,"constructor",{value:m,configurable:!0}),m.displayName=c(g,l,"GeneratorFunction"),e.isGeneratorFunction=function(t){var e="function"==typeof t&&t.constructor;return!!e&&(e===m||"GeneratorFunction"===(e.displayName||e.name))},e.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,g):(t.__proto__=g,c(t,l,"GeneratorFunction")),t.prototype=Object.create(v),t},e.awrap=function(t){return{__await:t}},w(x.prototype),c(x.prototype,s,(function(){return this})),e.AsyncIterator=x,e.async=function(t,n,o,r,a){void 0===a&&(a=Promise);var i=new x(u(t,n,o,r),a);return e.isGeneratorFunction(n)?i:i.next().then((function(t){return t.done?t.value:i.next()}))},w(v),c(v,l,"Generator"),c(v,i,(function(){return this})),c(v,"toString",(function(){return"[object Generator]"})),e.keys=function(t){var e=Object(t),n=[];for(var o in e)n.push(o);return n.reverse(),function t(){for(;n.length;){var o=n.pop();if(o in e)return t.value=o,t.done=!1,t}return t.done=!0,t}},e.values=A,S.prototype={constructor:S,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=void 0,this.done=!1,this.delegate=null,this.method="next",this.arg=void 0,this.tryEntries.forEach(L),!t)for(var e in this)"t"===e.charAt(0)&&o.call(this,e)&&!isNaN(+e.slice(1))&&(this[e]=void 0)},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var e=this;function n(n,o){return i.type="throw",i.arg=t,e.next=n,o&&(e.method="next",e.arg=void 0),!!o}for(var r=this.tryEntries.length-1;r>=0;--r){var a=this.tryEntries[r],i=a.completion;if("root"===a.tryLoc)return n("end");if(a.tryLoc<=this.prev){var s=o.call(a,"catchLoc"),l=o.call(a,"finallyLoc");if(s&&l){if(this.prev<a.catchLoc)return n(a.catchLoc,!0);if(this.prev<a.finallyLoc)return n(a.finallyLoc)}else if(s){if(this.prev<a.catchLoc)return n(a.catchLoc,!0)}else{if(!l)throw new Error("try statement without catch or finally");if(this.prev<a.finallyLoc)return n(a.finallyLoc)}}}},abrupt:function(t,e){for(var n=this.tryEntries.length-1;n>=0;--n){var r=this.tryEntries[n];if(r.tryLoc<=this.prev&&o.call(r,"finallyLoc")&&this.prev<r.finallyLoc){var a=r;break}}a&&("break"===t||"continue"===t)&&a.tryLoc<=e&&e<=a.finallyLoc&&(a=null);var i=a?a.completion:{};return i.type=t,i.arg=e,a?(this.method="next",this.next=a.finallyLoc,p):this.complete(i)},complete:function(t,e){if("throw"===t.type)throw t.arg;return"break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&e&&(this.next=e),p},finish:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.finallyLoc===t)return this.complete(n.completion,n.afterLoc),L(n),p}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc===t){var o=n.completion;if("throw"===o.type){var r=o.arg;L(n)}return r}}throw new Error("illegal catch attempt")},delegateYield:function(t,e,n){return this.delegate={iterator:A(t),resultName:e,nextLoc:n},"next"===this.method&&(this.arg=void 0),p}},e}function e(t,e,n,o,r,a,i){try{var s=t[a](i),l=s.value}catch(t){return void n(t)}s.done?e(l):Promise.resolve(l).then(o,r)}function n(t){return function(){var n=this,o=arguments;return new Promise((function(r,a){var i=t.apply(n,o);function s(t){e(i,r,a,s,l,"next",t)}function l(t){e(i,r,a,s,l,"throw",t)}s(void 0)}))}}function o(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,o=new Array(e);n<e;n++)o[n]=t[n];return o}function r(t,e){var n="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!n){if(Array.isArray(t)||(n=function(t,e){if(t){if("string"==typeof t)return o(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?o(t,e):void 0}}(t))||e&&t&&"number"==typeof t.length){n&&(t=n);var r=0,a=function(){};return{s:a,n:function(){return r>=t.length?{done:!0}:{done:!1,value:t[r++]}},e:function(t){throw t},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,s=!0,l=!1;return{s:function(){n=n.call(t)},n:function(){var t=n.next();return s=t.done,t},e:function(t){l=!0,i=t},f:function(){try{s||null==n.return||n.return()}finally{if(l)throw i}}}}!function(){var e="";try{var o="srgb";window.matchMedia("(color-gamut: rec2020)").matches?o="rec2020":window.matchMedia("(color-gamut: p3)").matches&&(o="display-p3"),e=CSS.supports("color: color(display-p3 1 0 0)")?o:"srgb"}catch(t){e="srgb"}var a=null,i=!1,s="",l="",c={},u=/.*?_(\d+)$/,d=!1,p="",f=!1,m=/^( {1,4}|\t)/,g="\n_O='<div class=\"color-command\">{}</div>'\n_N='swatch'\n_M='transparent'\n_L='pycon'\n_K='playground'\n_J='gamut'\n_I='exceptions'\n_H='color'\n_G='highlight'\n_F='class'\n_E='eval'\n_D='<string>'\n_C=None\n_B=True\n_A=False\nimport xml.etree.ElementTree as Etree\nfrom collections.abc import Sequence,Mapping\nfrom collections import namedtuple\nimport ast\nfrom io import StringIO\nimport sys,re\nfrom functools import partial\nfrom pygments import highlight\nfrom pygments.lexers import get_lexer_by_name\nfrom pygments.formatters import find_formatter_class\nfrom coloraide import Color\nfrom coloraide.interpolate import Interpolator,normalize_domain\ntry:from coloraide_extras.everything import ColorAll\nexcept ImportError:from coloraide.everything import ColorAll\nPY310=(3,10)<=sys.version_info\nPY311=(3,11)<=sys.version_info\nWEBSPACE='srgb'\nAST_BLOCKS=ast.If,ast.For,ast.While,ast.Try,ast.With,ast.FunctionDef,ast.ClassDef,ast.AsyncFor,ast.AsyncWith,ast.AsyncFunctionDef\nif PY310:AST_BLOCKS=AST_BLOCKS+(ast.Match,)\nif PY311:AST_BLOCKS=AST_BLOCKS+(ast.TryStar,)\nRE_INIT=re.compile('^\\\\s*#\\\\s*pragma:\\\\s*init\\\\n(.*?)#\\\\s*pragma:\\\\s*init\\\\n',re.DOTALL|re.I)\nRE_COLOR_START=re.compile('(?i)(?:\\\\b(?<![-#&$])(?:color|hsla?|lch|lab|hwb|rgba?)\\\\(|\\\\b(?<![-#&$])[\\\\w]{3,}(?![(-])\\\\b|(?<![&])#)')\nLIVE_INIT='\\nfrom coloraide import *\\nimport coloraide\\ntry:\\n    import coloraide_extras\\n    from coloraide_extras.everything import ColorAll as Color\\nexcept ImportError:\\n    from coloraide.everything import ColorAll as Color\\n'\ntemplate='<div class=\"playground\" id=\"__playground_{el_id}\">\\n<div class=\"playground-results\" id=\"__playground-results_{el_id}\">\\n{results}\\n</div>\\n<div class=\"playground-code hidden\" id=\"__playground-code_{el_id}\" data-search-exclude>\\n<form autocomplete=\"off\">\\n<textarea class=\"playground-inputs\" id=\"__playground-inputs_{el_id}\" spellcheck=\"false\">{raw_source}</textarea>\\n</form>\\n</div>\\n<div class=\"playground-footer\" data-search-exclude>\\n<hr>\\n<button id=\"__playground-edit_{el_id}\" class=\"playground-edit\" title=\"Edit the current snippet\">Edit</button>\\n<button id=\"__playground-share_{el_id}\" class=\"playground-share\" title=\"Copy URL to current snippet\">Share</button>\\n<button id=\"__playground-run_{el_id}\" class=\"playground-run hidden\" title=\"Run code (Ctrl + Enter)\">Run</button>\\n<button id=\"__playground-cancel_{el_id}\" class=\"playground-cancel hidden\" title=\"Cancel edit (Escape)\">Cancel</button>\\n<span class=\\'gamut\\'>Gamut: {gamut}</span>\\n</div>\\n</div>'\ncode_id=0\nclass Ramp(list):0\nclass Steps(list):0\nclass Row(list):0\nclass ColorTuple(namedtuple('ColorTuple',['string',_H])):0\nclass AtomicString(str):0\nclass Break(Exception):0\nclass Continue(Exception):0\nHtmlRow=Row\nHtmlSteps=Steps\nHtmlGradient=Ramp\ndef _escape(txt):txt=txt.replace('&','&amp;');txt=txt.replace('<','&lt;');txt=txt.replace('>','&gt;');return txt\nclass StreamOut:\n\tdef __init__(self):self.old=sys.stdout;self.stdout=StringIO();sys.stdout=self.stdout\n\tdef read(self):\n\t\tvalue=''\n\t\tif self.stdout is not _C:self.stdout.flush();value=self.stdout.getvalue();self.stdout=StringIO();sys.stdout=self.stdout\n\t\treturn value\n\tdef __enter__(self):return self\n\tdef __exit__(self,type,value,traceback):sys.stdout=self.old;self.old=_C;self.stdout=_C\ndef get_colors(result):\n\tdomain=[]\n\tif isinstance(result,AtomicString):yield find_colors(result)\n\tif isinstance(result,Row):yield Row([ColorTuple(c.to_string(fit=_A),c.clone())if isinstance(c,Color)else ColorTuple(c,ColorAll(c))for c in result])\n\telif isinstance(result,(Steps,Ramp)):t=type(result);yield t([c.clone()if isinstance(c,Color)else ColorAll(c)for c in result])\n\telif isinstance(result,Color):yield[ColorTuple(result.to_string(fit=_A),result.clone())]\n\telif isinstance(result,Interpolator):\n\t\tif result.domain:domain=result.domain;result.domain=normalize_domain(result.domain)\n\t\tgrad=Ramp(result.steps(steps=5,max_delta_e=2.3))\n\t\tif domain:result.domain=domain;domain=[]\n\t\tyield grad\n\telif isinstance(result,str):\n\t\ttry:yield[ColorTuple(result,ColorAll(result))]\n\t\texcept Exception:pass\n\telif isinstance(result,(list,tuple)):\n\t\tfor r in result:\n\t\t\tfor x in get_colors(r):\n\t\t\t\tif x:yield x\ndef find_colors(text):\n\tcolors=[]\n\tfor m in RE_COLOR_START.finditer(text):\n\t\tstart=m.start();mcolor=ColorAll.match(text,start=start)\n\t\tif mcolor is not _C:colors.append(ColorTuple(text[mcolor.start:mcolor.end],mcolor.color))\n\treturn colors\ndef evaluate_with(node,g,loop,index=0):\n\tl=len(node.items)-1;withitem=node.items[index]\n\tif withitem.context_expr:\n\t\twith eval(compile(ast.Expression(withitem.context_expr),_D,_E),g)as w:\n\t\t\tg[withitem.optional_vars.id]=w\n\t\t\tif index<l:evaluate_with(node,g,loop,index+1)\n\t\t\telse:\n\t\t\t\tfor n in node.body:yield from evaluate(n,g,loop)\n\telse:\n\t\twith eval(compile(ast.Expression(withitem.context_expr),_D,_E),g):\n\t\t\tif index<l:evaluate_with(node,g,loop,index+1)\n\t\t\telse:\n\t\t\t\tfor n in node.body:yield from evaluate(n,g,loop)\ndef compare_match(s,g,node):\n\tif isinstance(node,ast.MatchOr):\n\t\tfor pattern in node.patterns:\n\t\t\tif compare_match(s,g,pattern):return _B\n\telif isinstance(node,ast.MatchValue):p=eval(compile(ast.Expression(node.value),_D,_E),g);return s==p\n\telif isinstance(node,ast.MatchSingleton):return s is node.value\n\telif isinstance(node,ast.MatchSequence):\n\t\tif isinstance(s,Sequence):\n\t\t\tstar=isinstance(node.patterns[-1],ast.MatchStar);l1,l2=len(s),len(node.patterns)\n\t\t\tif star and l1>=l2-1 or l1==l2:\n\t\t\t\tfor (e,p) in enumerate(node.patterns[:-1]if star else node.patterns):\n\t\t\t\t\tif not compare_match(s[e],g,p):return _A\n\t\t\t\tif star and node.patterns[-1].name:g[node.patterns[-1].name]=s[l2-1:]\n\t\t\t\treturn _B\n\t\treturn _A\n\telif isinstance(node,ast.MatchMapping):\n\t\tif isinstance(s,Mapping):\n\t\t\tstar=node.rest;l1,l2=len(s),len(node.patterns)\n\t\t\tif star and l1>=l2 or l1==l2:\n\t\t\t\tkeys=set()\n\t\t\t\tfor (kp,vp) in zip(node.keys,node.patterns):\n\t\t\t\t\tkey=eval(compile(ast.Expression(kp),_D,_E),g);keys.add(key)\n\t\t\t\t\tif key not in s:return _A\n\t\t\t\t\tif not compare_match(s[key],g,vp):return _A\n\t\t\t\tif star:g[star]={k:v for(k,v)in s.items()if k not in keys}\n\t\t\t\treturn _B\n\t\treturn _A\n\telif isinstance(node,ast.MatchClass):\n\t\tname=g.get(node.cls.id,_C)\n\t\tif name is _C:raise NameError(\"name '{}' is not defined\".format(node.cls.id))\n\t\tif not isinstance(s,name):return _A\n\t\tma=getattr(s,'__match_args__',tuple());l1=len(ma);l2=len(node.patterns)\n\t\tif l1<l2:raise TypeError('{}() accepts {} positional sub-patterns ({} given)'.format(name,l1,l2))\n\t\tfor (e,p) in enumerate(node.patterns):\n\t\t\tif not hasattr(s,ma[e]):return _A\n\t\t\tif not compare_match(getattr(s,ma[e]),g,p):return _A\n\t\tfor (a,p) in zip(node.kwd_attrs,node.kwd_patterns):\n\t\t\tif not hasattr(s,a):return _A\n\t\t\tif not compare_match(getattr(s,a),g,p):return _A\n\t\treturn _B\n\telif isinstance(node,ast.MatchAs):\n\t\tif node.name is not _C:g[node.name]=s\n\t\tif node.pattern:return compare_match(s,g,node.pattern)\n\t\treturn _B\n\traise RuntimeError('Unknown Match pattern {}'.format(str(node)))\ndef evaluate_except(node,e,g,loop=_A):\n\tfor n in node.handlers:\n\t\tif n.name:g[n.name]=e\n\t\tif n.type is _C:\n\t\t\tfor ne in n.body:yield from evaluate(ne,g,loop)\n\t\t\tbreak\n\t\telif isinstance(e,eval(compile(ast.Expression(n.type),_D,_E),g)):\n\t\t\tfor ne in n.body:yield from evaluate(ne,g,loop)\n\t\t\tbreak\n\telse:raise\ndef evaluate(node,g,loop=_A):\n\tif loop and isinstance(node,ast.Break):raise Break\n\tif loop and isinstance(node,ast.Continue):raise Continue\n\tif isinstance(node,ast.Expr):_eval=ast.Expression(node.value);yield eval(compile(_eval,_D,_E),g)\n\telif isinstance(node,ast.If):\n\t\tif eval(compile(ast.Expression(node.test),_D,_E),g):\n\t\t\tfor n in node.body:yield from evaluate(n,g,loop)\n\t\telif node.orelse:\n\t\t\tfor n in node.orelse:yield from evaluate(n,g,loop)\n\telif isinstance(node,ast.While):\n\t\twhile eval(compile(ast.Expression(node.test),_D,_E),g):\n\t\t\ttry:\n\t\t\t\tfor n in node.body:yield from evaluate(n,g,_B)\n\t\t\texcept Break:break\n\t\t\texcept Continue:continue\n\t\telse:\n\t\t\tfor n in node.orelse:yield from evaluate(n,g,loop)\n\telif isinstance(node,ast.For):\n\t\tfor x in eval(compile(ast.Expression(node.iter),_D,_E),g):\n\t\t\tif isinstance(node.target,ast.Tuple):\n\t\t\t\tfor (e,t) in enumerate(node.target.dims):g[t.id]=x[e]\n\t\t\telse:g[node.target.id]=x\n\t\t\ttry:\n\t\t\t\tfor n in node.body:yield from evaluate(n,g,_B)\n\t\t\texcept Break:break\n\t\t\texcept Continue:continue\n\t\telse:\n\t\t\tfor n in node.orelse:yield from evaluate(n,g,loop)\n\telif isinstance(node,ast.Try):\n\t\ttry:\n\t\t\tfor n in node.body:yield from evaluate(n,g,loop)\n\t\texcept Exception as e:yield from evaluate_except(node,e,g,loop)\n\t\telse:\n\t\t\tfor n in node.orelse:yield from evaluate(n,g,loop)\n\t\tfinally:\n\t\t\tfor n in node.finalbody:yield from evaluate(n,g,loop)\n\telif PY311 and isinstance(node,ast.TryStar):\n\t\ttry:\n\t\t\tfor n in node.body:yield from evaluate(n,g,loop)\n\t\texcept ExceptionGroup as e:\n\t\t\tfor n in node.handlers:\n\t\t\t\tif n.name:g[n.name]=e\n\t\t\t\tm,e=e.split(eval(compile(ast.Expression(n.type),_D,_E),g))\n\t\t\t\tif m is not _C:\n\t\t\t\t\tfor ne in n.body:yield from evaluate(ne,g,loop)\n\t\t\t\tif e is _C:break\n\t\t\tif e is not _C:raise e\n\t\texcept Exception as e:yield from evaluate_except(node,e,g,loop)\n\t\telse:\n\t\t\tfor n in node.orelse:yield from evaluate(n,g,loop)\n\t\tfinally:\n\t\t\tfor n in node.finalbody:yield from evaluate(n,g,loop)\n\telif PY310 and isinstance(node,ast.Match):\n\t\ts=eval(compile(ast.Expression(node.subject),_D,_E),g)\n\t\tfor c in node.cases:\n\t\t\tif compare_match(s,g,c.pattern):\n\t\t\t\tif not c.guard or eval(compile(ast.Expression(c.guard),_D,_E),g):\n\t\t\t\t\tfor n in c.body:yield from evaluate(n,g,loop)\n\t\t\t\t\tbreak\n\telif isinstance(node,ast.With):yield from evaluate_with(node,g,loop)\n\telse:_exec=ast.Module([node],[]);exec(compile(_exec,_D,'exec'),g);yield _C\ndef execute(cmd,no_except=_B,inline=_A,init='',g=_C):\n\tA='\\n';console='';colors=[]\n\tif g is _C:g={'Ramp':Ramp,'Steps':Steps,'Row':Row,'HtmlRow':HtmlRow,'HtmlSteps':HtmlSteps,'HtmlGradient':HtmlGradient}\n\tif init:execute(init.strip(),g=g)\n\tm=RE_INIT.match(cmd)\n\tif m:block_init=m.group(1);src=cmd[m.end():];execute(block_init,g=g)\n\telse:src=cmd\n\tlines=src.split(A)\n\ttry:tree=ast.parse(src)\n\texcept Exception as e:\n\t\tif no_except:\n\t\t\tif not inline:from pymdownx.superfences import SuperFencesException;raise SuperFencesException from e\n\t\t\telse:from pymdownx.inlinehilite import InlineHiliteException;raise InlineHiliteException from e\n\t\timport traceback;return '{}'.format(traceback.format_exc()),colors\n\tfor node in tree.body:\n\t\tresult=[];start=node.lineno;end=node.end_lineno;stmt=lines[start-1:end];command=''\n\t\tfor (i,line) in enumerate(stmt,0):\n\t\t\tif i==0:stmt[i]='>>> '+line\n\t\t\telse:stmt[i]='... '+line\n\t\tcommand+=A.join(stmt)\n\t\tif isinstance(node,AST_BLOCKS):command+='\\n... '\n\t\ttry:\n\t\t\twith StreamOut()as s:\n\t\t\t\tfor x in evaluate(node,g):\n\t\t\t\t\tresult.append(x);text=s.read()\n\t\t\t\t\tif text:result.append(AtomicString(text))\n\t\t\t\tconsole+=command\n\t\texcept Exception as e:\n\t\t\tif no_except:\n\t\t\t\tif not inline:from pymdownx.superfences import SuperFencesException;raise SuperFencesException from e\n\t\t\t\telse:from pymdownx.inlinehilite import InlineHiliteException;raise InlineHiliteException from e\n\t\t\timport traceback;console+='{}\\n{}'.format(command,traceback.format_exc());break\n\t\tresult_text=A\n\t\tfor r in result:\n\t\t\tif r is _C:continue\n\t\t\tfor clist in get_colors(r):\n\t\t\t\tif clist:colors.append(clist)\n\t\t\tresult_text+='{}{}'.format(repr(r)if isinstance(r,str)and not isinstance(r,AtomicString)else str(r),A if not isinstance(r,AtomicString)else'')\n\t\tconsole+=result_text\n\treturn console,colors\ndef colorize(src,lang,**options):HtmlFormatter=find_formatter_class('html');lexer=get_lexer_by_name(lang,**options);formatter=HtmlFormatter(cssclass=_G,wrapcode=_B);return highlight(src,lexer,formatter).strip()\ndef color_command_validator(language,inputs,options,attrs,md):\n\tvalid_inputs=set([_I,'play'])\n\tfor (k,v) in inputs.items():\n\t\tif k in valid_inputs:options[k]=_B;continue\n\t\tattrs[k]=v\n\treturn _B\ndef _color_command_console(colors,gamut=WEBSPACE):\n\tC='{} {}%';B=' ';A='<div class=\"swatch-bar\">{}</div>';el='';bar=_A;values=[]\n\tfor item in colors:\n\t\tif isinstance(item,(HtmlGradient,Steps)):\n\t\t\tcurrent=total=percent=last=0\n\t\t\tif isinstance(item,Steps):total=len(item);percent=100/total;current=percent\n\t\t\tif bar:el+=A.format(B.join(values));values=[]\n\t\t\tsub_el1='<div class=\"swatch-bar\"><span class=\"swatch swatch-gradient\">{}</span></div>';style='--swatch-stops: ';stops=[]\n\t\t\tfor (e,color) in enumerate(item):\n\t\t\t\tcolor.fit(gamut)\n\t\t\t\tif current:\n\t\t\t\t\tstops.append(C.format(color.convert(gamut).to_string(),str(last)));stops.append(C.format(color.convert(gamut).to_string(),str(current)));last=current\n\t\t\t\t\tif e<total-1:current+=percent\n\t\t\t\t\telse:current=100\n\t\t\t\telse:stops.append(color.convert(gamut).to_string())\n\t\t\tif not stops:stops.extend([_M]*2)\n\t\t\tif len(stops)==1:stops.append(stops[0])\n\t\t\tstyle+=','.join(stops);sub_el2='<span class=\"swatch-color\" style=\"{}\"></span>'.format(style);el+=sub_el1.format(sub_el2);bar=_A\n\t\telse:\n\t\t\tis_row=_A\n\t\t\tif isinstance(item,Row):\n\t\t\t\tis_row=_B\n\t\t\t\tif bar and values:el+=A.format(B.join(values));values=[]\n\t\t\t\tbar=_A\n\t\t\tbar=_B\n\t\t\tfor color in item:\n\t\t\t\tbase_classes=_N\n\t\t\t\tif not color.color.in_gamut(gamut):base_classes+=' out-of-gamut'\n\t\t\t\tcolor.color.fit(gamut);srgb=color.color.convert(gamut);value1=srgb.to_string(alpha=_A);value2=srgb.to_string();style='--swatch-stops: {} 50%, {} 50%'.format(value1,value2);title=color.string;classes=base_classes;c='<span class=\"swatch-color\" style=\"{style}\"></span>'.format(style=style);c='<span class=\"{classes}\" title=\"{title}&#013;Copy to clipboard\">{color}</span>'.format(classes=classes,color=c,title=title);values.append(c)\n\t\t\tif is_row and values:el+=A.format(B.join(values));values=[];bar=_A\n\tif bar:el+=A.format(B.join(values));values=[]\n\treturn el\ndef _color_command_formatter(src='',language='',class_name=_C,options=_C,md='',init='',**kwargs):\n\tB='formatter';A='fenced_code_block';global code_id;from pymdownx.superfences import SuperFencesException;gamut=kwargs.get(_J,WEBSPACE);play=options.get('play',_A)if options is not _C else _A\n\tif not play and language==_K:play=_B\n\tif not play:return md.preprocessors[A].extension.superfences[0][B](src=src,class_name=class_name,language='py',md=md,options=options,**kwargs)\n\ttry:\n\t\tif len(md.preprocessors[A].extension.stash)==0:code_id=0\n\t\texceptions=options.get(_I,_A)if options is not _C else _A;console,colors=execute(src.strip(),not exceptions,init=init);el=_color_command_console(colors,gamut=gamut);el+=md.preprocessors[A].extension.superfences[0][B](src=console,class_name=_G,language=_L,md=md,options=options,**kwargs);el=_O.format(el);el=template.format(el_id=code_id,raw_source=_escape(src),results=el,gamut=gamut);code_id+=1\n\texcept SuperFencesException:raise\n\texcept Exception:from pymdownx import superfences;import traceback;print(traceback.format_exc());return superfences.fence_code_format(src,'text',class_name,options,md,**kwargs)\n\treturn el\ndef color_command_formatter(init='',gamut=WEBSPACE):return partial(_color_command_formatter,init=init,gamut=gamut)\ndef _color_formatter(src='',language='',class_name=_C,md='',exceptions=_B,init='',gamut=WEBSPACE):\n\tE='backtick';D='title';C='Only one color allowed';B=' 50%';A='span';from pymdownx.inlinehilite import InlineHiliteException\n\ttry:\n\t\tresult=src.strip()\n\t\ttry:color=ColorAll(result.strip())\n\t\texcept Exception:\n\t\t\t_,colors=execute(result,exceptions,inline=_B,init=init)\n\t\t\tif len(colors)!=1 or len(colors[0])!=1:\n\t\t\t\tif exceptions:raise InlineHiliteException(C)\n\t\t\t\telse:raise ValueError(C)\n\t\t\tcolor=colors[0][0].color;result=colors[0][0].string\n\t\tel=Etree.Element(A);stops=[]\n\t\tif not color.in_gamut(gamut):\n\t\t\tcolor.fit(gamut);attributes={_F:'swatch out-of-gamut',D:result};sub_el=Etree.SubElement(el,A,attributes);stops.append(color.convert(gamut).to_string(hex=_B,alpha=_A))\n\t\t\tif color[-1]<1.0:stops[-1]+=B;stops.append(color.convert(gamut).to_string(hex=_B)+B)\n\t\telse:\n\t\t\tattributes={_F:_N,D:result};sub_el=Etree.SubElement(el,A,attributes);stops.append(color.convert(gamut).to_string(hex=_B,alpha=_A))\n\t\t\tif color[-1]<1.0:stops[-1]+=B;stops.append(color.convert(gamut).to_string(hex=_B)+B)\n\t\tif not stops:stops.extend([_M]*2)\n\t\tif len(stops)==1:stops.append(stops[0])\n\t\tEtree.SubElement(sub_el,A,{_F:'swatch-color','style':'--swatch-stops: {};'.format(','.join(stops))});el.append(md.inlinePatterns[E].handle_code('css-color',result))\n\texcept InlineHiliteException:raise\n\texcept Exception:import traceback;print(traceback.format_exc());el=md.inlinePatterns[E].handle_code('text',src)\n\treturn el\ndef color_formatter(init='',gamut=WEBSPACE):return partial(_color_formatter,init=init,gamut=gamut)\ndef _live_color_command_formatter(src,init='',gamut=WEBSPACE):\n\ttry:\n\t\tconsole,colors=execute(src.strip(),_A,init=init);el=_color_command_console(colors,gamut=gamut)\n\t\tif not colors:el+='<div class=\"swatch-bar\"></div>'\n\t\tel+=colorize(console,_L,**{'python3':_B,'stripnl':_A});el=_O.format(el)\n\texcept Exception:import traceback;return '<div class=\"color-command\"><div class=\"swatch-bar\"></div>{}</div>'.format(colorize(traceback.format_exc(),_L))\n\treturn el\ndef live_color_command_formatter(init='',gamut=WEBSPACE):return partial(_live_color_command_formatter,init=init,gamut=gamut)\ndef live_color_command_validator(language,inputs,options,attrs,md):value=color_command_validator(language,inputs,options,attrs,md);options[_I]=_B;return value\ndef render_console(*args,**kwargs):\n\tC='.swatch-bar';B='code';A='id_num';from js import document;gamut=kwargs.get(_J,WEBSPACE)\n\ttry:\n\t\tinputs=document.getElementById('__playground-inputs_{}'.format(globals()[A]));results=document.getElementById('__playground-results_{}'.format(globals()[A]));footer=document.querySelector('#__playground_{} .gamut'.format(globals()[A]));result=live_color_command_formatter(LIVE_INIT,gamut)(inputs.value);temp=document.createElement('div');temp.innerHTML=result;cmd=results.querySelector('.color-command')\n\t\tfor el in cmd.querySelectorAll(C):el.remove()\n\t\tfor el in temp.querySelectorAll(C):cmd.insertBefore(el,cmd.lastChild)\n\t\tfooter.innerHTML='Gamut: {}'.format(gamut);pre=cmd.querySelector('pre');pre.replaceChild(temp.querySelector(B),pre.querySelector(B));temp.remove();scrollingElement=results.querySelector(B);scrollingElement.scrollTop=scrollingElement.scrollHeight\n\texcept Exception as e:print(e)\ndef render_notebook(*args,**kwargs):\n\tM='diagram';L='pymdownx.blocks.tab';K='pymdownx.blocks.admonition';J='pymdownx.arithmatex';I='pymdownx.keys';H='pymdownx.magiclink';G='pymdownx.inlinehilite';F='pymdownx.superfences';E='markdown.extensions.smarty';D='markdown.extensions.toc';C='validator';B='format';A='name';import markdown;from pymdownx import slugs,superfences;from js import document;gamut=kwargs.get(_J,WEBSPACE);text=globals().get('content','');extensions=[D,E,'pymdownx.betterem','markdown.extensions.attr_list','markdown.extensions.tables','markdown.extensions.abbr','markdown.extensions.footnotes',F,'pymdownx.highlight',G,H,'pymdownx.tilde','pymdownx.caret','pymdownx.smartsymbols','pymdownx.emoji','pymdownx.escapeall','pymdownx.tasklist','pymdownx.striphtml','pymdownx.snippets',I,'pymdownx.saneheaders',J,K,'pymdownx.blocks.details','pymdownx.blocks.html','pymdownx.blocks.definition',L];extension_configs={D:{'slugify':slugs.slugify(case='lower'),'permalink':''},E:{'smart_quotes':_A},J:{'generic':_B,'block_tag':'pre'},F:{'preserve_tabs':_B,'custom_fences':[{A:M,_F:M,B:superfences.fence_code_format},{A:_K,_F:_K,B:color_command_formatter(LIVE_INIT,gamut),C:live_color_command_validator},{A:'python',_F:_G,B:color_command_formatter(LIVE_INIT,gamut),C:live_color_command_validator},{A:'py',_F:_G,B:color_command_formatter(LIVE_INIT,gamut),C:live_color_command_validator}]},G:{'custom_inline':[{A:_H,_F:_H,B:color_formatter(LIVE_INIT,gamut)}]},H:{'repo_url_shortener':_B,'repo_url_shorthand':_B,'social_url_shorthand':_B,'user':'facelessuser','repo':'coloraide'},I:{'separator':'＋'},L:{'alternate_style':_B},K:{'types':['new','settings','note','abstract','info','tip','success','question','warning','failure','danger','bug','example','quote']}}\n\ttry:html=markdown.markdown(text,extensions=extensions,extension_configs=extension_configs)\n\texcept Exception:html=''\n\tcontent=document.getElementById('__notebook-render');content.innerHTML=html\n\naction = globals().get('action')\nif action == 'notebook':\n    callback = render_notebook\nelse:\n    callback = render_console\n\ncallback(gamut='".concat(e,"')\n"),h=window.colorNotebook.defaultPlayground,_=function(t){return"\n/// new | This notebook is powered by [Pyodide](https://github.com/pyodide/pyodide). Learn more [here](?notebook=https://gist.githubusercontent.com/facelessuser/7c819668b5eb248ecb9ac608d91391cf/raw/playground.md). Preview, convert, interpolate, and explore!\n///\n\n````````py play\n".concat(t,"\n````````\n")},y=!1,v=!1,w=function(){f=!0,window.document.dispatchEvent(new Event("DOMContentLoaded",{bubbles:!0,cancelable:!0})),window.document$.next()},x=function(t){var e=window.pageXOffset||(document.documentElement||document.body.parentNode||document.body).scrollLeft,n=window.pageYOffset||(document.documentElement||document.body.parentNode||document.body).scrollTop;t.style.height="5px",t.style.height="".concat(t.scrollHeight,"px"),window.scrollTo(e,n)},b=function(t){return encodeURIComponent(t).replace(/[.!'()*]/g,(function(t){return"%".concat(t.charCodeAt(0).toString(16))}))},E=function(){var e=n(t().mark((function e(n){var o;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return(o=document.getElementById("__playground-inputs_".concat(n))).setAttribute("readonly",""),a.globals.set("id_num",n),a.globals.set("action","playground"),t.next=6,a.runPythonAsync(g);case 6:o.removeAttribute("readonly");case 7:case"end":return t.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),k=function(){var e=n(t().mark((function e(n){var o;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return a.globals.set("content",n),a.globals.set("action","notebook"),t.next=4,a.runPythonAsync(g);case 4:(o=document.getElementById("__notebook-input"))&&(s=n,o.value=n),window.location.hash&&(window.location.href=window.location.href);case 7:case"end":return t.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),L=function(){var e=n(t().mark((function e(n){var o,i,s,l,c,u;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(d){t.next=5;break}return d=!0,t.next=4,loadPyodide({indexURL:"https://cdn.jsdelivr.net/pyodide/v0.23.0/full/",fullStdLib:!1});case 4:a=t.sent;case 5:if((y||!n)&&(v||n)){t.next=14;break}o="".concat(window.location.origin,"/").concat(window.location.pathname.split("/")[1],"/playground/"),i=n?window.colorNotebook.notebookWheels:window.colorNotebook.playgroundWheels,s=[],n?y=!0:v=!0,l=r(i);try{for(l.s();!(c=l.n()).done;)(u=c.value).endsWith(".whl")?s.push(o+u):s.push(u)}catch(t){l.e(t)}finally{l.f()}return t.next=14,a.loadPackage(s);case 14:case"end":return t.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),S=function(t,e,n){var o=null==e?"Loading...":e,r=n?"loading relative":"loading",a=document.createElement("template");a.innerHTML='<div class="'.concat(r,'"><div class="loader"></div><div>').concat(o,"</div></div>"),t.appendChild(a.content.firstChild)},A=function(t){t.querySelector(".loading")&&t.removeChild(t.querySelector(".loading"))},C=function(t){if("Tab"===t.key){var e=t.target;if(e.selectionStart!==e.selectionEnd){t.preventDefault();for(var n=e.selectionStart,o=e.selectionEnd,r=e.value;n>0&&"\n"!==r[n-1];)n--;for(;o>0&&"\n"!==r[o-1]&&o<r.length;)o++;for(var a=r.substr(n,o-n).split("\n"),i=0;i<a.length;i++)i===a.length-1&&0===a[i].length||(t.shiftKey?a[i]=a[i].replace(m,""):a[i]="    ".concat(a[i]));a=a.join("\n"),e.value=r.substr(0,n)+a+r.substr(o),e.selectionStart=n,e.selectionEnd=n+a.length}}},B=function(){var e=n(t().mark((function e(o){var r;return t().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:r=document.getElementById("__notebook-source"),document.querySelectorAll(".playground").forEach((function(e){var a=e.id.replace(u,"$1"),d=document.getElementById("__playground-inputs_".concat(a)),p=document.getElementById("__playground-results_".concat(a)),f=document.getElementById("__playground-code_".concat(a)),m=document.querySelector("button#__playground-edit_".concat(a)),g=document.querySelector("button#__playground-share_".concat(a)),h=document.querySelector("button#__playground-run_".concat(a)),_=document.querySelector("button#__playground-cancel_".concat(a));if(d.addEventListener("input",(function(){x(d)})),d.addEventListener("keydown",C),r&&o){var y=document.getElementById("__notebook-input");y.addEventListener("input",(function(t){x(t.target)})),y.addEventListener("keydown",C),document.getElementById("__notebook-edit").addEventListener("click",(function(){c[y.id]=y.value,document.getElementById("__notebook-render").classList.toggle("hidden"),document.getElementById("__notebook-source").classList.toggle("hidden"),x(document.getElementById("__notebook-input"))})),document.getElementById("__notebook-md-gist").addEventListener("click",function(){var e=n(t().mark((function e(n){var o;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:null!==(o=prompt("Please enter link to the Markdown page source:",l))&&(o=b(o),n.preventDefault(),history.pushState({notebook:o},"","?".concat(new URLSearchParams("notebook=".concat(o)).toString())),I(!1));case 2:case"end":return t.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()),document.getElementById("__notebook-py-gist").addEventListener("click",function(){var e=n(t().mark((function e(n){var o;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:null!==(o=prompt("Please enter the link to the Python code source:",l))&&(o=b(o),n.preventDefault(),history.pushState({source:o},"","?".concat(new URLSearchParams("source=".concat(o)).toString())),I(!1));case 2:case"end":return t.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()),document.getElementById("__notebook-input").value=s,document.getElementById("__notebook-cancel").addEventListener("click",(function(){y.value=c[y.id],delete c[y.id],document.getElementById("__notebook-render").classList.toggle("hidden"),document.getElementById("__notebook-source").classList.toggle("hidden")})),document.getElementById("__notebook-submit").addEventListener("click",n(t().mark((function e(){var n,o;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return n=document.getElementById("__notebook-render"),s=document.getElementById("__notebook-input").value,n.classList.toggle("hidden"),document.getElementById("__notebook-source").classList.toggle("hidden"),o=document.querySelector("article"),S(o,"Loading Notebook..."),n.innerHTML="",c={},t.next=10,L(!0);case 10:return t.next=12,k(s);case 12:return t.next=14,B();case 14:A(o),w();case 16:case"end":return t.stop()}}),e)}))))}d.addEventListener("touchmove",(function(t){t.stopPropagation()})),p.addEventListener("click",(function(t){var e=t.target;if(e.matches("span.swatch-color")){var n="",o=e.parentNode;if(!o.matches("span.swatch-gradient")){if(n=(n=o.getAttribute("title").replace("Copy to clipboard","")).replace("\n",""),window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",n);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){var r=document.createElement("textarea");r.textContent=n,r.style.position="fixed",document.body.appendChild(r),r.select();try{return document.execCommand("copy")}catch(t){return prompt("Copy to clipboard: Ctrl+C, Enter",n)}finally{document.body.removeChild(r)}}}}})),m.addEventListener("click",n(t().mark((function e(){return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:c[a]=d.value,f.classList.toggle("hidden"),p.classList.toggle("hidden"),h.classList.toggle("hidden"),_.classList.toggle("hidden"),m.classList.toggle("hidden"),g.classList.toggle("hidden"),x(d),d.focus();case 9:case"end":return t.stop()}}),e)})))),g.addEventListener("click",n(t().mark((function e(){var o,r,a,i,s;return t().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:o=window.location.pathname.split("/")[1],r=b(d.value),a=window.location,i="/playground/",a.pathname.startsWith("/".concat(o,"/"))&&(i="/".concat(o,"/playground/")),(s="".concat(a.protocol,"//").concat(a.host).concat(i,"?code=").concat(r)).length>2e3?alert("Code must be small enough to generate a shareable URL under 2000 characters!"):navigator.clipboard.writeText(s).then(n(t().mark((function e(){return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:alert("Link copied to clipboard :)");case 1:case"end":return t.stop()}}),e)}))),n(t().mark((function e(){return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:alert("Failed to copy link clipboard!");case 1:case"end":return t.stop()}}),e)}))));case 7:case"end":return e.stop()}}),e)})))),h.addEventListener("click",n(t().mark((function e(){var n,o;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(!i){t.next=2;break}return t.abrupt("return");case 2:return i=!0,n=f.querySelector("form"),S(n,null,!0),(o=document.querySelectorAll(".playground .playground-run"))&&o.forEach((function(t){t.setAttribute("disabled","")})),t.next=9,L(!1);case 9:return p.querySelector("code").innerHTML="",t.next=12,E(a);case 12:o&&o.forEach((function(t){t.removeAttribute("disabled")})),A(n),f.classList.toggle("hidden"),p.classList.toggle("hidden"),m.classList.toggle("hidden"),g.classList.toggle("hidden"),h.classList.toggle("hidden"),_.classList.toggle("hidden"),delete c[a],i=!1;case 22:case"end":return t.stop()}}),e)})))),_.addEventListener("click",(function(){d.value=c[a],delete c[a],f.classList.toggle("hidden"),p.classList.toggle("hidden"),m.classList.toggle("hidden"),g.classList.toggle("hidden"),h.classList.toggle("hidden"),_.classList.toggle("hidden")}))}));case 3:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),I=function(){var e=n(t().mark((function e(o,r){var a,i,s,u,d,f,m,g,y;return t().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(c={},!window.location.pathname.endsWith("/playground/")){e.next=32;break}if(a=r||new URLSearchParams(window.location.search),i="Loading Pyodide...",s="Loading Notebook...",u=a.has("source")?a.get("source"):a.get("notebook"),d=document.querySelector("article"),null===u||!u.trim()){e.next=16;break}return S(d,i),e.next=11,L(!0);case 11:A(d),S(d,s);try{f=a.has("source")?"source":"notebook",p=decodeURIComponent(a.toString()),m="",g=new XMLHttpRequest,l=u,g.open("GET",u,!0),g.onload=n(t().mark((function e(){return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return 4===g.readyState&&200===g.status&&(m=g.responseText),"source"===f&&(m=_(m)),t.next=4,k(m);case 4:return t.next=6,B(o);case 6:A(d),w();case 8:case"end":return t.stop()}}),e)}))),g.send()}catch(t){}e.next=30;break;case 16:return l="",y=_(a.has("code")?a.get("code"):h),p=decodeURIComponent(a.toString()),S(d,i),e.next=22,L(!0);case 22:return A(d),S(d,s),e.next=26,k(y);case 26:return e.next=28,B(o);case 28:A(d),w();case 30:e.next=35;break;case 32:l="",p="",B(o);case 35:case"end":return e.stop()}}),e)})));return function(t,n){return e.apply(this,arguments)}}();document.addEventListener("click",(function(t){var e=window.location.pathname.split("/")[1],n=t.target||t.srcElement;if("A"===n.tagName&&I&&n.getAttribute("href")&&n.host===window.location.host&&window.location.pathname==="/".concat(e,"/playground/")&&window.location.pathname===n.pathname&&window.location.search!==n.search){t.preventDefault();var o=new URLSearchParams(n.search);I(!1,o)}}),!0),window.addEventListener("popstate",(function(){var t=window.location.pathname.split("/")[1];window.location.pathname==="/".concat(t,"/playground/")&&(decodeURIComponent(new URLSearchParams(window.location.search).toString())!==p&&I(!1))})),window.addEventListener("unload",(function(){f=!1})),window.document$.subscribe((function(){f?f=!1:I(!0)}))}()}();
-//# sourceMappingURL=extra-notebook-3d99782d.js.map
+function _typeof(t){return _typeof="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},_typeof(t)}var runtime=function(t){"use strict";var e,n=Object.prototype,o=n.hasOwnProperty,r=Object.defineProperty||function(t,e,n){t[e]=n.value},a="function"==typeof Symbol?Symbol:{},i=a.iterator||"@@iterator",s=a.asyncIterator||"@@asyncIterator",l=a.toStringTag||"@@toStringTag";function c(t,e,n){return Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{c({},"")}catch(t){c=function(t,e,n){return t[e]=n}}function u(t,e,n,o){var a=e&&e.prototype instanceof _?e:_,i=Object.create(a.prototype),s=new I(o||[]);return r(i,"_invoke",{value:S(t,n,s)}),i}function d(t,e,n){try{return{type:"normal",arg:t.call(e,n)}}catch(t){return{type:"throw",arg:t}}}t.wrap=u;var p="suspendedStart",f="suspendedYield",m="executing",g="completed",h={};function _(){}function y(){}function v(){}var w={};c(w,i,(function(){return this}));var x=Object.getPrototypeOf,b=x&&x(x(T([])));b&&b!==n&&o.call(b,i)&&(w=b);var E=v.prototype=_.prototype=Object.create(w);function k(t){["next","throw","return"].forEach((function(e){c(t,e,(function(t){return this._invoke(e,t)}))}))}function L(t,e){function n(r,a,i,s){var l=d(t[r],t,a);if("throw"!==l.type){var c=l.arg,u=c.value;return u&&"object"===_typeof(u)&&o.call(u,"__await")?e.resolve(u.__await).then((function(t){n("next",t,i,s)}),(function(t){n("throw",t,i,s)})):e.resolve(u).then((function(t){c.value=t,i(c)}),(function(t){return n("throw",t,i,s)}))}s(l.arg)}var a;r(this,"_invoke",{value:function(t,o){function r(){return new e((function(e,r){n(t,o,e,r)}))}return a=a?a.then(r,r):r()}})}function S(t,e,n){var o=p;return function(r,a){if(o===m)throw new Error("Generator is already running");if(o===g){if("throw"===r)throw a;return O()}for(n.method=r,n.arg=a;;){var i=n.delegate;if(i){var s=A(i,n);if(s){if(s===h)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(o===p)throw o=g,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o=m;var l=d(t,e,n);if("normal"===l.type){if(o=n.done?g:f,l.arg===h)continue;return{value:l.arg,done:n.done}}"throw"===l.type&&(o=g,n.method="throw",n.arg=l.arg)}}}function A(t,n){var o=n.method,r=t.iterator[o];if(r===e)return n.delegate=null,"throw"===o&&t.iterator.return&&(n.method="return",n.arg=e,A(t,n),"throw"===n.method)||"return"!==o&&(n.method="throw",n.arg=new TypeError("The iterator does not provide a '"+o+"' method")),h;var a=d(r,t.iterator,n.arg);if("throw"===a.type)return n.method="throw",n.arg=a.arg,n.delegate=null,h;var i=a.arg;return i?i.done?(n[t.resultName]=i.value,n.next=t.nextLoc,"return"!==n.method&&(n.method="next",n.arg=e),n.delegate=null,h):i:(n.method="throw",n.arg=new TypeError("iterator result is not an object"),n.delegate=null,h)}function C(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function B(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function I(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(C,this),this.reset(!0)}function T(t){if(t){var n=t[i];if(n)return n.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var r=-1,a=function n(){for(;++r<t.length;)if(o.call(t,r))return n.value=t[r],n.done=!1,n;return n.value=e,n.done=!0,n};return a.next=a}}return{next:O}}function O(){return{value:e,done:!0}}return y.prototype=v,r(E,"constructor",{value:v,configurable:!0}),r(v,"constructor",{value:y,configurable:!0}),y.displayName=c(v,l,"GeneratorFunction"),t.isGeneratorFunction=function(t){var e="function"==typeof t&&t.constructor;return!!e&&(e===y||"GeneratorFunction"===(e.displayName||e.name))},t.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,v):(t.__proto__=v,c(t,l,"GeneratorFunction")),t.prototype=Object.create(E),t},t.awrap=function(t){return{__await:t}},k(L.prototype),c(L.prototype,s,(function(){return this})),t.AsyncIterator=L,t.async=function(e,n,o,r,a){void 0===a&&(a=Promise);var i=new L(u(e,n,o,r),a);return t.isGeneratorFunction(n)?i:i.next().then((function(t){return t.done?t.value:i.next()}))},k(E),c(E,l,"Generator"),c(E,i,(function(){return this})),c(E,"toString",(function(){return"[object Generator]"})),t.keys=function(t){var e=Object(t),n=[];for(var o in e)n.push(o);return n.reverse(),function t(){for(;n.length;){var o=n.pop();if(o in e)return t.value=o,t.done=!1,t}return t.done=!0,t}},t.values=T,I.prototype={constructor:I,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=e,this.done=!1,this.delegate=null,this.method="next",this.arg=e,this.tryEntries.forEach(B),!t)for(var n in this)"t"===n.charAt(0)&&o.call(this,n)&&!isNaN(+n.slice(1))&&(this[n]=e)},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var n=this;function r(o,r){return s.type="throw",s.arg=t,n.next=o,r&&(n.method="next",n.arg=e),!!r}for(var a=this.tryEntries.length-1;a>=0;--a){var i=this.tryEntries[a],s=i.completion;if("root"===i.tryLoc)return r("end");if(i.tryLoc<=this.prev){var l=o.call(i,"catchLoc"),c=o.call(i,"finallyLoc");if(l&&c){if(this.prev<i.catchLoc)return r(i.catchLoc,!0);if(this.prev<i.finallyLoc)return r(i.finallyLoc)}else if(l){if(this.prev<i.catchLoc)return r(i.catchLoc,!0)}else{if(!c)throw new Error("try statement without catch or finally");if(this.prev<i.finallyLoc)return r(i.finallyLoc)}}}},abrupt:function(t,e){for(var n=this.tryEntries.length-1;n>=0;--n){var r=this.tryEntries[n];if(r.tryLoc<=this.prev&&o.call(r,"finallyLoc")&&this.prev<r.finallyLoc){var a=r;break}}a&&("break"===t||"continue"===t)&&a.tryLoc<=e&&e<=a.finallyLoc&&(a=null);var i=a?a.completion:{};return i.type=t,i.arg=e,a?(this.method="next",this.next=a.finallyLoc,h):this.complete(i)},complete:function(t,e){if("throw"===t.type)throw t.arg;return"break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&e&&(this.next=e),h},finish:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.finallyLoc===t)return this.complete(n.completion,n.afterLoc),B(n),h}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc===t){var o=n.completion;if("throw"===o.type){var r=o.arg;B(n)}return r}}throw new Error("illegal catch attempt")},delegateYield:function(t,n,o){return this.delegate={iterator:T(t),resultName:n,nextLoc:o},"next"===this.method&&(this.arg=e),h}},t}("object"===("undefined"==typeof module?"undefined":_typeof(module))?module.exports:{});try{regeneratorRuntime=runtime}catch(t){"object"===("undefined"==typeof globalThis?"undefined":_typeof(globalThis))?globalThis.regeneratorRuntime=runtime:Function("r","regeneratorRuntime = r")(runtime)}!function(){"use strict";function t(){t=function(){return e};var e={},n=Object.prototype,o=n.hasOwnProperty,r=Object.defineProperty||function(t,e,n){t[e]=n.value},a="function"==typeof Symbol?Symbol:{},i=a.iterator||"@@iterator",s=a.asyncIterator||"@@asyncIterator",l=a.toStringTag||"@@toStringTag";function c(t,e,n){return Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{c({},"")}catch(t){c=function(t,e,n){return t[e]=n}}function u(t,e,n,o){var a=e&&e.prototype instanceof f?e:f,i=Object.create(a.prototype),s=new S(o||[]);return r(i,"_invoke",{value:b(t,n,s)}),i}function d(t,e,n){try{return{type:"normal",arg:t.call(e,n)}}catch(t){return{type:"throw",arg:t}}}e.wrap=u;var p={};function f(){}function m(){}function g(){}var h={};c(h,i,(function(){return this}));var _=Object.getPrototypeOf,y=_&&_(_(A([])));y&&y!==n&&o.call(y,i)&&(h=y);var v=g.prototype=f.prototype=Object.create(h);function w(t){["next","throw","return"].forEach((function(e){c(t,e,(function(t){return this._invoke(e,t)}))}))}function x(t,e){function n(r,a,i,s){var l=d(t[r],t,a);if("throw"!==l.type){var c=l.arg,u=c.value;return u&&"object"==_typeof(u)&&o.call(u,"__await")?e.resolve(u.__await).then((function(t){n("next",t,i,s)}),(function(t){n("throw",t,i,s)})):e.resolve(u).then((function(t){c.value=t,i(c)}),(function(t){return n("throw",t,i,s)}))}s(l.arg)}var a;r(this,"_invoke",{value:function(t,o){function r(){return new e((function(e,r){n(t,o,e,r)}))}return a=a?a.then(r,r):r()}})}function b(t,e,n){var o="suspendedStart";return function(r,a){if("executing"===o)throw new Error("Generator is already running");if("completed"===o){if("throw"===r)throw a;return C()}for(n.method=r,n.arg=a;;){var i=n.delegate;if(i){var s=E(i,n);if(s){if(s===p)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if("suspendedStart"===o)throw o="completed",n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o="executing";var l=d(t,e,n);if("normal"===l.type){if(o=n.done?"completed":"suspendedYield",l.arg===p)continue;return{value:l.arg,done:n.done}}"throw"===l.type&&(o="completed",n.method="throw",n.arg=l.arg)}}}function E(t,e){var n=e.method,o=t.iterator[n];if(void 0===o)return e.delegate=null,"throw"===n&&t.iterator.return&&(e.method="return",e.arg=void 0,E(t,e),"throw"===e.method)||"return"!==n&&(e.method="throw",e.arg=new TypeError("The iterator does not provide a '"+n+"' method")),p;var r=d(o,t.iterator,e.arg);if("throw"===r.type)return e.method="throw",e.arg=r.arg,e.delegate=null,p;var a=r.arg;return a?a.done?(e[t.resultName]=a.value,e.next=t.nextLoc,"return"!==e.method&&(e.method="next",e.arg=void 0),e.delegate=null,p):a:(e.method="throw",e.arg=new TypeError("iterator result is not an object"),e.delegate=null,p)}function k(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function L(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function S(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(k,this),this.reset(!0)}function A(t){if(t){var e=t[i];if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var n=-1,r=function e(){for(;++n<t.length;)if(o.call(t,n))return e.value=t[n],e.done=!1,e;return e.value=void 0,e.done=!0,e};return r.next=r}}return{next:C}}function C(){return{value:void 0,done:!0}}return m.prototype=g,r(v,"constructor",{value:g,configurable:!0}),r(g,"constructor",{value:m,configurable:!0}),m.displayName=c(g,l,"GeneratorFunction"),e.isGeneratorFunction=function(t){var e="function"==typeof t&&t.constructor;return!!e&&(e===m||"GeneratorFunction"===(e.displayName||e.name))},e.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,g):(t.__proto__=g,c(t,l,"GeneratorFunction")),t.prototype=Object.create(v),t},e.awrap=function(t){return{__await:t}},w(x.prototype),c(x.prototype,s,(function(){return this})),e.AsyncIterator=x,e.async=function(t,n,o,r,a){void 0===a&&(a=Promise);var i=new x(u(t,n,o,r),a);return e.isGeneratorFunction(n)?i:i.next().then((function(t){return t.done?t.value:i.next()}))},w(v),c(v,l,"Generator"),c(v,i,(function(){return this})),c(v,"toString",(function(){return"[object Generator]"})),e.keys=function(t){var e=Object(t),n=[];for(var o in e)n.push(o);return n.reverse(),function t(){for(;n.length;){var o=n.pop();if(o in e)return t.value=o,t.done=!1,t}return t.done=!0,t}},e.values=A,S.prototype={constructor:S,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=void 0,this.done=!1,this.delegate=null,this.method="next",this.arg=void 0,this.tryEntries.forEach(L),!t)for(var e in this)"t"===e.charAt(0)&&o.call(this,e)&&!isNaN(+e.slice(1))&&(this[e]=void 0)},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var e=this;function n(n,o){return i.type="throw",i.arg=t,e.next=n,o&&(e.method="next",e.arg=void 0),!!o}for(var r=this.tryEntries.length-1;r>=0;--r){var a=this.tryEntries[r],i=a.completion;if("root"===a.tryLoc)return n("end");if(a.tryLoc<=this.prev){var s=o.call(a,"catchLoc"),l=o.call(a,"finallyLoc");if(s&&l){if(this.prev<a.catchLoc)return n(a.catchLoc,!0);if(this.prev<a.finallyLoc)return n(a.finallyLoc)}else if(s){if(this.prev<a.catchLoc)return n(a.catchLoc,!0)}else{if(!l)throw new Error("try statement without catch or finally");if(this.prev<a.finallyLoc)return n(a.finallyLoc)}}}},abrupt:function(t,e){for(var n=this.tryEntries.length-1;n>=0;--n){var r=this.tryEntries[n];if(r.tryLoc<=this.prev&&o.call(r,"finallyLoc")&&this.prev<r.finallyLoc){var a=r;break}}a&&("break"===t||"continue"===t)&&a.tryLoc<=e&&e<=a.finallyLoc&&(a=null);var i=a?a.completion:{};return i.type=t,i.arg=e,a?(this.method="next",this.next=a.finallyLoc,p):this.complete(i)},complete:function(t,e){if("throw"===t.type)throw t.arg;return"break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&e&&(this.next=e),p},finish:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.finallyLoc===t)return this.complete(n.completion,n.afterLoc),L(n),p}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc===t){var o=n.completion;if("throw"===o.type){var r=o.arg;L(n)}return r}}throw new Error("illegal catch attempt")},delegateYield:function(t,e,n){return this.delegate={iterator:A(t),resultName:e,nextLoc:n},"next"===this.method&&(this.arg=void 0),p}},e}function e(t,e,n,o,r,a,i){try{var s=t[a](i),l=s.value}catch(t){return void n(t)}s.done?e(l):Promise.resolve(l).then(o,r)}function n(t){return function(){var n=this,o=arguments;return new Promise((function(r,a){var i=t.apply(n,o);function s(t){e(i,r,a,s,l,"next",t)}function l(t){e(i,r,a,s,l,"throw",t)}s(void 0)}))}}function o(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,o=new Array(e);n<e;n++)o[n]=t[n];return o}function r(t,e){var n="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!n){if(Array.isArray(t)||(n=function(t,e){if(t){if("string"==typeof t)return o(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?o(t,e):void 0}}(t))||e&&t&&"number"==typeof t.length){n&&(t=n);var r=0,a=function(){};return{s:a,n:function(){return r>=t.length?{done:!0}:{done:!1,value:t[r++]}},e:function(t){throw t},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,s=!0,l=!1;return{s:function(){n=n.call(t)},n:function(){var t=n.next();return s=t.done,t},e:function(t){l=!0,i=t},f:function(){try{s||null==n.return||n.return()}finally{if(l)throw i}}}}!function(){var e="";try{var o="srgb";window.matchMedia("(color-gamut: rec2020)").matches?o="rec2020":window.matchMedia("(color-gamut: p3)").matches&&(o="display-p3"),e=CSS.supports("color: color(display-p3 1 0 0)")?o:"srgb"}catch(t){e="srgb"}var a=null,i=!1,s="",l="",c={},u=/.*?_(\d+)$/,d=!1,p="",f=!1,m=/^( {1,4}|\t)/,g="\n_O='<div class=\"color-command\">{}</div>'\n_N='swatch'\n_M='transparent'\n_L='pycon'\n_K='playground'\n_J='gamut'\n_I='exceptions'\n_H='color'\n_G='highlight'\n_F='class'\n_E='eval'\n_D='<string>'\n_C=None\n_B=True\n_A=False\nimport xml.etree.ElementTree as Etree\nfrom collections.abc import Sequence,Mapping\nfrom collections import namedtuple\nimport ast\nfrom io import StringIO\nimport sys,re\nfrom functools import partial\nfrom pygments import highlight\nfrom pygments.lexers import get_lexer_by_name\nfrom pygments.formatters import find_formatter_class\nfrom coloraide import Color\nfrom coloraide.interpolate import Interpolator,normalize_domain\ntry:from coloraide_extras.everything import ColorAll\nexcept ImportError:from coloraide.everything import ColorAll\nPY310=(3,10)<=sys.version_info\nPY311=(3,11)<=sys.version_info\nWEBSPACE='srgb'\nAST_BLOCKS=ast.If,ast.For,ast.While,ast.Try,ast.With,ast.FunctionDef,ast.ClassDef,ast.AsyncFor,ast.AsyncWith,ast.AsyncFunctionDef\nif PY310:AST_BLOCKS=AST_BLOCKS+(ast.Match,)\nif PY311:AST_BLOCKS=AST_BLOCKS+(ast.TryStar,)\nRE_INIT=re.compile('^\\\\s*#\\\\s*pragma:\\\\s*init\\\\n(.*?)#\\\\s*pragma:\\\\s*init\\\\n',re.DOTALL|re.I)\nRE_COLOR_START=re.compile('(?i)(?:\\\\b(?<![-#&$])(?:color|hsla?|lch|lab|hwb|rgba?)\\\\(|\\\\b(?<![-#&$])[\\\\w]{3,}(?![(-])\\\\b|(?<![&])#)')\nLIVE_INIT='\\nfrom coloraide import *\\nimport coloraide\\ntry:\\n    import coloraide_extras\\n    from coloraide_extras.everything import ColorAll as Color\\nexcept ImportError:\\n    from coloraide.everything import ColorAll as Color\\n'\ntemplate='<div class=\"playground\" id=\"__playground_{el_id}\">\\n<div class=\"playground-results\" id=\"__playground-results_{el_id}\">\\n{results}\\n</div>\\n<div class=\"playground-code hidden\" id=\"__playground-code_{el_id}\" data-search-exclude>\\n<form autocomplete=\"off\">\\n<textarea class=\"playground-inputs\" id=\"__playground-inputs_{el_id}\" spellcheck=\"false\">{raw_source}</textarea>\\n</form>\\n</div>\\n<div class=\"playground-footer\" data-search-exclude>\\n<hr>\\n<button id=\"__playground-edit_{el_id}\" class=\"playground-edit\" title=\"Edit the current snippet\">Edit</button>\\n<button id=\"__playground-share_{el_id}\" class=\"playground-share\" title=\"Copy URL to current snippet\">Share</button>\\n<button id=\"__playground-run_{el_id}\" class=\"playground-run hidden\" title=\"Run code (Ctrl + Enter)\">Run</button>\\n<button id=\"__playground-cancel_{el_id}\" class=\"playground-cancel hidden\" title=\"Cancel edit (Escape)\">Cancel</button>\\n<span class=\\'gamut\\'>Gamut: {gamut}</span>\\n</div>\\n</div>'\ncode_id=0\nclass Ramp(list):0\nclass Steps(list):0\nclass Row(list):0\nclass ColorTuple(namedtuple('ColorTuple',['string',_H])):0\nclass AtomicString(str):0\nclass Break(Exception):0\nclass Continue(Exception):0\nHtmlRow=Row\nHtmlSteps=Steps\nHtmlGradient=Ramp\ndef _escape(txt):txt=txt.replace('&','&amp;');txt=txt.replace('<','&lt;');txt=txt.replace('>','&gt;');return txt\nclass StreamOut:\n\tdef __init__(self):self.old=sys.stdout;self.stdout=StringIO();sys.stdout=self.stdout\n\tdef read(self):\n\t\tvalue=''\n\t\tif self.stdout is not _C:self.stdout.flush();value=self.stdout.getvalue();self.stdout=StringIO();sys.stdout=self.stdout\n\t\treturn value\n\tdef __enter__(self):return self\n\tdef __exit__(self,type,value,traceback):sys.stdout=self.old;self.old=_C;self.stdout=_C\ndef get_colors(result):\n\tdomain=[]\n\tif isinstance(result,AtomicString):yield find_colors(result)\n\tif isinstance(result,Row):yield Row([ColorTuple(c.to_string(fit=_A),c.clone())if isinstance(c,Color)else ColorTuple(c,ColorAll(c))for c in result])\n\telif isinstance(result,(Steps,Ramp)):t=type(result);yield t([c.clone()if isinstance(c,Color)else ColorAll(c)for c in result])\n\telif isinstance(result,Color):yield[ColorTuple(result.to_string(fit=_A),result.clone())]\n\telif isinstance(result,Interpolator):\n\t\tif result.domain:domain=result.domain;result.domain=normalize_domain(result.domain)\n\t\tgrad=Ramp(result.steps(steps=5,max_delta_e=2.3))\n\t\tif domain:result.domain=domain;domain=[]\n\t\tyield grad\n\telif isinstance(result,str):\n\t\ttry:yield[ColorTuple(result,ColorAll(result))]\n\t\texcept Exception:pass\n\telif isinstance(result,(list,tuple)):\n\t\tfor r in result:\n\t\t\tfor x in get_colors(r):\n\t\t\t\tif x:yield x\ndef find_colors(text):\n\tcolors=[]\n\tfor m in RE_COLOR_START.finditer(text):\n\t\tstart=m.start();mcolor=ColorAll.match(text,start=start)\n\t\tif mcolor is not _C:colors.append(ColorTuple(text[mcolor.start:mcolor.end],mcolor.color))\n\treturn colors\ndef evaluate_with(node,g,loop,index=0):\n\tl=len(node.items)-1;withitem=node.items[index]\n\tif withitem.context_expr:\n\t\twith eval(compile(ast.Expression(withitem.context_expr),_D,_E),g)as w:\n\t\t\tg[withitem.optional_vars.id]=w\n\t\t\tif index<l:evaluate_with(node,g,loop,index+1)\n\t\t\telse:\n\t\t\t\tfor n in node.body:yield from evaluate(n,g,loop)\n\telse:\n\t\twith eval(compile(ast.Expression(withitem.context_expr),_D,_E),g):\n\t\t\tif index<l:evaluate_with(node,g,loop,index+1)\n\t\t\telse:\n\t\t\t\tfor n in node.body:yield from evaluate(n,g,loop)\ndef compare_match(s,g,node):\n\tif isinstance(node,ast.MatchOr):\n\t\tfor pattern in node.patterns:\n\t\t\tif compare_match(s,g,pattern):return _B\n\telif isinstance(node,ast.MatchValue):p=eval(compile(ast.Expression(node.value),_D,_E),g);return s==p\n\telif isinstance(node,ast.MatchSingleton):return s is node.value\n\telif isinstance(node,ast.MatchSequence):\n\t\tif isinstance(s,Sequence):\n\t\t\tstar=isinstance(node.patterns[-1],ast.MatchStar);l1,l2=len(s),len(node.patterns)\n\t\t\tif star and l1>=l2-1 or l1==l2:\n\t\t\t\tfor (e,p) in enumerate(node.patterns[:-1]if star else node.patterns):\n\t\t\t\t\tif not compare_match(s[e],g,p):return _A\n\t\t\t\tif star and node.patterns[-1].name:g[node.patterns[-1].name]=s[l2-1:]\n\t\t\t\treturn _B\n\t\treturn _A\n\telif isinstance(node,ast.MatchMapping):\n\t\tif isinstance(s,Mapping):\n\t\t\tstar=node.rest;l1,l2=len(s),len(node.patterns)\n\t\t\tif star and l1>=l2 or l1==l2:\n\t\t\t\tkeys=set()\n\t\t\t\tfor (kp,vp) in zip(node.keys,node.patterns):\n\t\t\t\t\tkey=eval(compile(ast.Expression(kp),_D,_E),g);keys.add(key)\n\t\t\t\t\tif key not in s:return _A\n\t\t\t\t\tif not compare_match(s[key],g,vp):return _A\n\t\t\t\tif star:g[star]={k:v for(k,v)in s.items()if k not in keys}\n\t\t\t\treturn _B\n\t\treturn _A\n\telif isinstance(node,ast.MatchClass):\n\t\tname=g.get(node.cls.id,_C)\n\t\tif name is _C:raise NameError(\"name '{}' is not defined\".format(node.cls.id))\n\t\tif not isinstance(s,name):return _A\n\t\tma=getattr(s,'__match_args__',tuple());l1=len(ma);l2=len(node.patterns)\n\t\tif l1<l2:raise TypeError('{}() accepts {} positional sub-patterns ({} given)'.format(name,l1,l2))\n\t\tfor (e,p) in enumerate(node.patterns):\n\t\t\tif not hasattr(s,ma[e]):return _A\n\t\t\tif not compare_match(getattr(s,ma[e]),g,p):return _A\n\t\tfor (a,p) in zip(node.kwd_attrs,node.kwd_patterns):\n\t\t\tif not hasattr(s,a):return _A\n\t\t\tif not compare_match(getattr(s,a),g,p):return _A\n\t\treturn _B\n\telif isinstance(node,ast.MatchAs):\n\t\tif node.name is not _C:g[node.name]=s\n\t\tif node.pattern:return compare_match(s,g,node.pattern)\n\t\treturn _B\n\traise RuntimeError('Unknown Match pattern {}'.format(str(node)))\ndef evaluate_except(node,e,g,loop=_A):\n\tfor n in node.handlers:\n\t\tif n.name:g[n.name]=e\n\t\tif n.type is _C:\n\t\t\tfor ne in n.body:yield from evaluate(ne,g,loop)\n\t\t\tbreak\n\t\telif isinstance(e,eval(compile(ast.Expression(n.type),_D,_E),g)):\n\t\t\tfor ne in n.body:yield from evaluate(ne,g,loop)\n\t\t\tbreak\n\telse:raise\ndef evaluate(node,g,loop=_A):\n\tif loop and isinstance(node,ast.Break):raise Break\n\tif loop and isinstance(node,ast.Continue):raise Continue\n\tif isinstance(node,ast.Expr):_eval=ast.Expression(node.value);yield eval(compile(_eval,_D,_E),g)\n\telif isinstance(node,ast.If):\n\t\tif eval(compile(ast.Expression(node.test),_D,_E),g):\n\t\t\tfor n in node.body:yield from evaluate(n,g,loop)\n\t\telif node.orelse:\n\t\t\tfor n in node.orelse:yield from evaluate(n,g,loop)\n\telif isinstance(node,ast.While):\n\t\twhile eval(compile(ast.Expression(node.test),_D,_E),g):\n\t\t\ttry:\n\t\t\t\tfor n in node.body:yield from evaluate(n,g,_B)\n\t\t\texcept Break:break\n\t\t\texcept Continue:continue\n\t\telse:\n\t\t\tfor n in node.orelse:yield from evaluate(n,g,loop)\n\telif isinstance(node,ast.For):\n\t\tfor x in eval(compile(ast.Expression(node.iter),_D,_E),g):\n\t\t\tif isinstance(node.target,ast.Tuple):\n\t\t\t\tfor (e,t) in enumerate(node.target.dims):g[t.id]=x[e]\n\t\t\telse:g[node.target.id]=x\n\t\t\ttry:\n\t\t\t\tfor n in node.body:yield from evaluate(n,g,_B)\n\t\t\texcept Break:break\n\t\t\texcept Continue:continue\n\t\telse:\n\t\t\tfor n in node.orelse:yield from evaluate(n,g,loop)\n\telif isinstance(node,ast.Try):\n\t\ttry:\n\t\t\tfor n in node.body:yield from evaluate(n,g,loop)\n\t\texcept Exception as e:yield from evaluate_except(node,e,g,loop)\n\t\telse:\n\t\t\tfor n in node.orelse:yield from evaluate(n,g,loop)\n\t\tfinally:\n\t\t\tfor n in node.finalbody:yield from evaluate(n,g,loop)\n\telif PY311 and isinstance(node,ast.TryStar):\n\t\ttry:\n\t\t\tfor n in node.body:yield from evaluate(n,g,loop)\n\t\texcept ExceptionGroup as e:\n\t\t\tfor n in node.handlers:\n\t\t\t\tif n.name:g[n.name]=e\n\t\t\t\tm,e=e.split(eval(compile(ast.Expression(n.type),_D,_E),g))\n\t\t\t\tif m is not _C:\n\t\t\t\t\tfor ne in n.body:yield from evaluate(ne,g,loop)\n\t\t\t\tif e is _C:break\n\t\t\tif e is not _C:raise e\n\t\texcept Exception as e:yield from evaluate_except(node,e,g,loop)\n\t\telse:\n\t\t\tfor n in node.orelse:yield from evaluate(n,g,loop)\n\t\tfinally:\n\t\t\tfor n in node.finalbody:yield from evaluate(n,g,loop)\n\telif PY310 and isinstance(node,ast.Match):\n\t\ts=eval(compile(ast.Expression(node.subject),_D,_E),g)\n\t\tfor c in node.cases:\n\t\t\tif compare_match(s,g,c.pattern):\n\t\t\t\tif not c.guard or eval(compile(ast.Expression(c.guard),_D,_E),g):\n\t\t\t\t\tfor n in c.body:yield from evaluate(n,g,loop)\n\t\t\t\t\tbreak\n\telif isinstance(node,ast.With):yield from evaluate_with(node,g,loop)\n\telse:_exec=ast.Module([node],[]);exec(compile(_exec,_D,'exec'),g);yield _C\ndef execute(cmd,no_except=_B,inline=_A,init='',g=_C):\n\tA='\\n';console='';colors=[]\n\tif g is _C:g={'Ramp':Ramp,'Steps':Steps,'Row':Row,'HtmlRow':HtmlRow,'HtmlSteps':HtmlSteps,'HtmlGradient':HtmlGradient}\n\tif init:execute(init.strip(),g=g)\n\tm=RE_INIT.match(cmd)\n\tif m:block_init=m.group(1);src=cmd[m.end():];execute(block_init,g=g)\n\telse:src=cmd\n\tlines=src.split(A)\n\ttry:tree=ast.parse(src)\n\texcept Exception as e:\n\t\tif no_except:\n\t\t\tif not inline:from pymdownx.superfences import SuperFencesException;raise SuperFencesException from e\n\t\t\telse:from pymdownx.inlinehilite import InlineHiliteException;raise InlineHiliteException from e\n\t\timport traceback;return '{}'.format(traceback.format_exc()),colors\n\tfor node in tree.body:\n\t\tresult=[];start=node.lineno;end=node.end_lineno;stmt=lines[start-1:end];command=''\n\t\tfor (i,line) in enumerate(stmt,0):\n\t\t\tif i==0:stmt[i]='>>> '+line\n\t\t\telse:stmt[i]='... '+line\n\t\tcommand+=A.join(stmt)\n\t\tif isinstance(node,AST_BLOCKS):command+='\\n... '\n\t\ttry:\n\t\t\twith StreamOut()as s:\n\t\t\t\tfor x in evaluate(node,g):\n\t\t\t\t\tresult.append(x);text=s.read()\n\t\t\t\t\tif text:result.append(AtomicString(text))\n\t\t\t\tconsole+=command\n\t\texcept Exception as e:\n\t\t\tif no_except:\n\t\t\t\tif not inline:from pymdownx.superfences import SuperFencesException;raise SuperFencesException from e\n\t\t\t\telse:from pymdownx.inlinehilite import InlineHiliteException;raise InlineHiliteException from e\n\t\t\timport traceback;console+='{}\\n{}'.format(command,traceback.format_exc());break\n\t\tresult_text=A\n\t\tfor r in result:\n\t\t\tif r is _C:continue\n\t\t\tfor clist in get_colors(r):\n\t\t\t\tif clist:colors.append(clist)\n\t\t\tresult_text+='{}{}'.format(repr(r)if isinstance(r,str)and not isinstance(r,AtomicString)else str(r),A if not isinstance(r,AtomicString)else'')\n\t\tconsole+=result_text\n\treturn console,colors\ndef colorize(src,lang,**options):HtmlFormatter=find_formatter_class('html');lexer=get_lexer_by_name(lang,**options);formatter=HtmlFormatter(cssclass=_G,wrapcode=_B);return highlight(src,lexer,formatter).strip()\ndef color_command_validator(language,inputs,options,attrs,md):\n\tvalid_inputs=set([_I,'play'])\n\tfor (k,v) in inputs.items():\n\t\tif k in valid_inputs:options[k]=_B;continue\n\t\tattrs[k]=v\n\treturn _B\ndef _color_command_console(colors,gamut=WEBSPACE):\n\tC='{} {}%';B=' ';A='<div class=\"swatch-bar\">{}</div>';el='';bar=_A;values=[]\n\tfor item in colors:\n\t\tis_grad=isinstance(item,HtmlGradient);is_steps=isinstance(item,Steps)\n\t\tif is_grad or is_steps:\n\t\t\tcurrent=total=percent=last=0\n\t\t\tif isinstance(item,Steps):total=len(item);percent=100/total;current=percent\n\t\t\tif bar:el+=A.format(B.join(values));values=[]\n\t\t\tsub_el1='<div class=\"swatch-bar\"><span class=\"swatch swatch-gradient\">{}</span></div>';style='--swatch-stops: ';stops=[]\n\t\t\tfor (e,color) in enumerate(item):\n\t\t\t\tcolor.fit(gamut);color_str=color.convert(gamut).to_string()\n\t\t\t\tif current:\n\t\t\t\t\tif is_steps:stops.append(C.format(color_str,str(last)));stops.append(C.format(color_str,str(current)))\n\t\t\t\t\telse:stops.append(color_str)\n\t\t\t\t\tlast=current\n\t\t\t\t\tif e<total-1:current+=percent\n\t\t\t\t\telse:current=100\n\t\t\t\telse:stops.append(color_str)\n\t\t\tif not stops:stops.extend([_M]*2)\n\t\t\tif len(stops)==1:stops.append(stops[0])\n\t\t\tstyle+=','.join(stops);sub_el2='<span class=\"swatch-color\" style=\"{}\"></span>'.format(style);el+=sub_el1.format(sub_el2);bar=_A\n\t\telse:\n\t\t\tis_row=_A\n\t\t\tif isinstance(item,Row):\n\t\t\t\tis_row=_B\n\t\t\t\tif bar and values:el+=A.format(B.join(values));values=[]\n\t\t\t\tbar=_A\n\t\t\tbar=_B\n\t\t\tfor color in item:\n\t\t\t\tbase_classes=_N\n\t\t\t\tif not color.color.in_gamut(gamut):base_classes+=' out-of-gamut'\n\t\t\t\tcolor.color.fit(gamut);srgb=color.color.convert(gamut);value1=srgb.to_string(alpha=_A);value2=srgb.to_string();style='--swatch-stops: {} 50%, {} 50%'.format(value1,value2);title=color.string;classes=base_classes;c='<span class=\"swatch-color\" style=\"{style}\"></span>'.format(style=style);c='<span class=\"{classes}\" title=\"{title}&#013;Copy to clipboard\">{color}</span>'.format(classes=classes,color=c,title=title);values.append(c)\n\t\t\tif is_row and values:el+=A.format(B.join(values));values=[];bar=_A\n\tif bar:el+=A.format(B.join(values));values=[]\n\treturn el\ndef _color_command_formatter(src='',language='',class_name=_C,options=_C,md='',init='',**kwargs):\n\tB='formatter';A='fenced_code_block';global code_id;from pymdownx.superfences import SuperFencesException;gamut=kwargs.get(_J,WEBSPACE);play=options.get('play',_A)if options is not _C else _A\n\tif not play and language==_K:play=_B\n\tif not play:return md.preprocessors[A].extension.superfences[0][B](src=src,class_name=class_name,language='py',md=md,options=options,**kwargs)\n\ttry:\n\t\tif len(md.preprocessors[A].extension.stash)==0:code_id=0\n\t\texceptions=options.get(_I,_A)if options is not _C else _A;console,colors=execute(src.strip(),not exceptions,init=init);el=_color_command_console(colors,gamut=gamut);el+=md.preprocessors[A].extension.superfences[0][B](src=console,class_name=_G,language=_L,md=md,options=options,**kwargs);el=_O.format(el);el=template.format(el_id=code_id,raw_source=_escape(src),results=el,gamut=gamut);code_id+=1\n\texcept SuperFencesException:raise\n\texcept Exception:from pymdownx import superfences;import traceback;print(traceback.format_exc());return superfences.fence_code_format(src,'text',class_name,options,md,**kwargs)\n\treturn el\ndef color_command_formatter(init='',gamut=WEBSPACE):return partial(_color_command_formatter,init=init,gamut=gamut)\ndef _color_formatter(src='',language='',class_name=_C,md='',exceptions=_B,init='',gamut=WEBSPACE):\n\tE='backtick';D='title';C='Only one color allowed';B=' 50%';A='span';from pymdownx.inlinehilite import InlineHiliteException\n\ttry:\n\t\tresult=src.strip()\n\t\ttry:color=ColorAll(result.strip())\n\t\texcept Exception:\n\t\t\t_,colors=execute(result,exceptions,inline=_B,init=init)\n\t\t\tif len(colors)!=1 or len(colors[0])!=1:\n\t\t\t\tif exceptions:raise InlineHiliteException(C)\n\t\t\t\telse:raise ValueError(C)\n\t\t\tcolor=colors[0][0].color;result=colors[0][0].string\n\t\tel=Etree.Element(A);stops=[]\n\t\tif not color.in_gamut(gamut):\n\t\t\tcolor.fit(gamut);attributes={_F:'swatch out-of-gamut',D:result};sub_el=Etree.SubElement(el,A,attributes);stops.append(color.convert(gamut).to_string(hex=_B,alpha=_A))\n\t\t\tif color[-1]<1.0:stops[-1]+=B;stops.append(color.convert(gamut).to_string(hex=_B)+B)\n\t\telse:\n\t\t\tattributes={_F:_N,D:result};sub_el=Etree.SubElement(el,A,attributes);stops.append(color.convert(gamut).to_string(hex=_B,alpha=_A))\n\t\t\tif color[-1]<1.0:stops[-1]+=B;stops.append(color.convert(gamut).to_string(hex=_B)+B)\n\t\tif not stops:stops.extend([_M]*2)\n\t\tif len(stops)==1:stops.append(stops[0])\n\t\tEtree.SubElement(sub_el,A,{_F:'swatch-color','style':'--swatch-stops: {};'.format(','.join(stops))});el.append(md.inlinePatterns[E].handle_code('css-color',result))\n\texcept InlineHiliteException:raise\n\texcept Exception:import traceback;print(traceback.format_exc());el=md.inlinePatterns[E].handle_code('text',src)\n\treturn el\ndef color_formatter(init='',gamut=WEBSPACE):return partial(_color_formatter,init=init,gamut=gamut)\ndef _live_color_command_formatter(src,init='',gamut=WEBSPACE):\n\ttry:\n\t\tconsole,colors=execute(src.strip(),_A,init=init);el=_color_command_console(colors,gamut=gamut)\n\t\tif not colors:el+='<div class=\"swatch-bar\"></div>'\n\t\tel+=colorize(console,_L,**{'python3':_B,'stripnl':_A});el=_O.format(el)\n\texcept Exception:import traceback;return '<div class=\"color-command\"><div class=\"swatch-bar\"></div>{}</div>'.format(colorize(traceback.format_exc(),_L))\n\treturn el\ndef live_color_command_formatter(init='',gamut=WEBSPACE):return partial(_live_color_command_formatter,init=init,gamut=gamut)\ndef live_color_command_validator(language,inputs,options,attrs,md):value=color_command_validator(language,inputs,options,attrs,md);options[_I]=_B;return value\ndef render_console(*args,**kwargs):\n\tC='.swatch-bar';B='code';A='id_num';from js import document;gamut=kwargs.get(_J,WEBSPACE)\n\ttry:\n\t\tinputs=document.getElementById('__playground-inputs_{}'.format(globals()[A]));results=document.getElementById('__playground-results_{}'.format(globals()[A]));footer=document.querySelector('#__playground_{} .gamut'.format(globals()[A]));result=live_color_command_formatter(LIVE_INIT,gamut)(inputs.value);temp=document.createElement('div');temp.innerHTML=result;cmd=results.querySelector('.color-command')\n\t\tfor el in cmd.querySelectorAll(C):el.remove()\n\t\tfor el in temp.querySelectorAll(C):cmd.insertBefore(el,cmd.lastChild)\n\t\tfooter.innerHTML='Gamut: {}'.format(gamut);pre=cmd.querySelector('pre');pre.replaceChild(temp.querySelector(B),pre.querySelector(B));temp.remove();scrollingElement=results.querySelector(B);scrollingElement.scrollTop=scrollingElement.scrollHeight\n\texcept Exception as e:print(e)\ndef render_notebook(*args,**kwargs):\n\tM='diagram';L='pymdownx.blocks.tab';K='pymdownx.blocks.admonition';J='pymdownx.arithmatex';I='pymdownx.keys';H='pymdownx.magiclink';G='pymdownx.inlinehilite';F='pymdownx.superfences';E='markdown.extensions.smarty';D='markdown.extensions.toc';C='validator';B='format';A='name';import markdown;from pymdownx import slugs,superfences;from js import document;gamut=kwargs.get(_J,WEBSPACE);text=globals().get('content','');extensions=[D,E,'pymdownx.betterem','markdown.extensions.attr_list','markdown.extensions.tables','markdown.extensions.abbr','markdown.extensions.footnotes',F,'pymdownx.highlight',G,H,'pymdownx.tilde','pymdownx.caret','pymdownx.smartsymbols','pymdownx.emoji','pymdownx.escapeall','pymdownx.tasklist','pymdownx.striphtml','pymdownx.snippets',I,'pymdownx.saneheaders',J,K,'pymdownx.blocks.details','pymdownx.blocks.html','pymdownx.blocks.definition',L];extension_configs={D:{'slugify':slugs.slugify(case='lower'),'permalink':''},E:{'smart_quotes':_A},J:{'generic':_B,'block_tag':'pre'},F:{'preserve_tabs':_B,'custom_fences':[{A:M,_F:M,B:superfences.fence_code_format},{A:_K,_F:_K,B:color_command_formatter(LIVE_INIT,gamut),C:live_color_command_validator},{A:'python',_F:_G,B:color_command_formatter(LIVE_INIT,gamut),C:live_color_command_validator},{A:'py',_F:_G,B:color_command_formatter(LIVE_INIT,gamut),C:live_color_command_validator}]},G:{'custom_inline':[{A:_H,_F:_H,B:color_formatter(LIVE_INIT,gamut)}]},H:{'repo_url_shortener':_B,'repo_url_shorthand':_B,'social_url_shorthand':_B,'user':'facelessuser','repo':'coloraide'},I:{'separator':'＋'},L:{'alternate_style':_B},K:{'types':['new','settings','note','abstract','info','tip','success','question','warning','failure','danger','bug','example','quote']}}\n\ttry:html=markdown.markdown(text,extensions=extensions,extension_configs=extension_configs)\n\texcept Exception:html=''\n\tcontent=document.getElementById('__notebook-render');content.innerHTML=html\n\naction = globals().get('action')\nif action == 'notebook':\n    callback = render_notebook\nelse:\n    callback = render_console\n\ncallback(gamut='".concat(e,"')\n"),h=window.colorNotebook.defaultPlayground,_=function(t){return"\n/// new | This notebook is powered by [Pyodide](https://github.com/pyodide/pyodide). Learn more [here](?notebook=https://gist.githubusercontent.com/facelessuser/7c819668b5eb248ecb9ac608d91391cf/raw/playground.md). Preview, convert, interpolate, and explore!\n///\n\n````````py play\n".concat(t,"\n````````\n")},y=!1,v=!1,w=function(){f=!0,window.document.dispatchEvent(new Event("DOMContentLoaded",{bubbles:!0,cancelable:!0})),window.document$.next()},x=function(t){var e=window.pageXOffset||(document.documentElement||document.body.parentNode||document.body).scrollLeft,n=window.pageYOffset||(document.documentElement||document.body.parentNode||document.body).scrollTop;t.style.height="5px",t.style.height="".concat(t.scrollHeight,"px"),window.scrollTo(e,n)},b=function(t){return encodeURIComponent(t).replace(/[.!'()*]/g,(function(t){return"%".concat(t.charCodeAt(0).toString(16))}))},E=function(){var e=n(t().mark((function e(n){var o;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return(o=document.getElementById("__playground-inputs_".concat(n))).setAttribute("readonly",""),a.globals.set("id_num",n),a.globals.set("action","playground"),t.next=6,a.runPythonAsync(g);case 6:o.removeAttribute("readonly");case 7:case"end":return t.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),k=function(){var e=n(t().mark((function e(n){var o;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return a.globals.set("content",n),a.globals.set("action","notebook"),t.next=4,a.runPythonAsync(g);case 4:(o=document.getElementById("__notebook-input"))&&(s=n,o.value=n),window.location.hash&&(window.location.href=window.location.href);case 7:case"end":return t.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),L=function(){var e=n(t().mark((function e(n){var o,i,s,l,c,u;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(d){t.next=5;break}return d=!0,t.next=4,loadPyodide({indexURL:"https://cdn.jsdelivr.net/pyodide/v0.23.0/full/",fullStdLib:!1});case 4:a=t.sent;case 5:if((y||!n)&&(v||n)){t.next=14;break}o="".concat(window.location.origin,"/").concat(window.location.pathname.split("/")[1],"/playground/"),i=n?window.colorNotebook.notebookWheels:window.colorNotebook.playgroundWheels,s=[],n?y=!0:v=!0,l=r(i);try{for(l.s();!(c=l.n()).done;)(u=c.value).endsWith(".whl")?s.push(o+u):s.push(u)}catch(t){l.e(t)}finally{l.f()}return t.next=14,a.loadPackage(s);case 14:case"end":return t.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),S=function(t,e,n){var o=null==e?"Loading...":e,r=n?"loading relative":"loading",a=document.createElement("template");a.innerHTML='<div class="'.concat(r,'"><div class="loader"></div><div>').concat(o,"</div></div>"),t.appendChild(a.content.firstChild)},A=function(t){t.querySelector(".loading")&&t.removeChild(t.querySelector(".loading"))},C=function(t){if("Tab"===t.key){var e=t.target;if(e.selectionStart!==e.selectionEnd){t.preventDefault();for(var n=e.selectionStart,o=e.selectionEnd,r=e.value;n>0&&"\n"!==r[n-1];)n--;for(;o>0&&"\n"!==r[o-1]&&o<r.length;)o++;for(var a=r.substr(n,o-n).split("\n"),i=0;i<a.length;i++)i===a.length-1&&0===a[i].length||(t.shiftKey?a[i]=a[i].replace(m,""):a[i]="    ".concat(a[i]));a=a.join("\n"),e.value=r.substr(0,n)+a+r.substr(o),e.selectionStart=n,e.selectionEnd=n+a.length}}},B=function(){var e=n(t().mark((function e(o){var r;return t().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:r=document.getElementById("__notebook-source"),document.querySelectorAll(".playground").forEach((function(e){var a=e.id.replace(u,"$1"),d=document.getElementById("__playground-inputs_".concat(a)),p=document.getElementById("__playground-results_".concat(a)),f=document.getElementById("__playground-code_".concat(a)),m=document.querySelector("button#__playground-edit_".concat(a)),g=document.querySelector("button#__playground-share_".concat(a)),h=document.querySelector("button#__playground-run_".concat(a)),_=document.querySelector("button#__playground-cancel_".concat(a));if(d.addEventListener("input",(function(){x(d)})),d.addEventListener("keydown",C),r&&o){var y=document.getElementById("__notebook-input");y.addEventListener("input",(function(t){x(t.target)})),y.addEventListener("keydown",C),document.getElementById("__notebook-edit").addEventListener("click",(function(){c[y.id]=y.value,document.getElementById("__notebook-render").classList.toggle("hidden"),document.getElementById("__notebook-source").classList.toggle("hidden"),x(document.getElementById("__notebook-input"))})),document.getElementById("__notebook-md-gist").addEventListener("click",function(){var e=n(t().mark((function e(n){var o;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:null!==(o=prompt("Please enter link to the Markdown page source:",l))&&(o=b(o),n.preventDefault(),history.pushState({notebook:o},"","?".concat(new URLSearchParams("notebook=".concat(o)).toString())),I(!1));case 2:case"end":return t.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()),document.getElementById("__notebook-py-gist").addEventListener("click",function(){var e=n(t().mark((function e(n){var o;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:null!==(o=prompt("Please enter the link to the Python code source:",l))&&(o=b(o),n.preventDefault(),history.pushState({source:o},"","?".concat(new URLSearchParams("source=".concat(o)).toString())),I(!1));case 2:case"end":return t.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()),document.getElementById("__notebook-input").value=s,document.getElementById("__notebook-cancel").addEventListener("click",(function(){y.value=c[y.id],delete c[y.id],document.getElementById("__notebook-render").classList.toggle("hidden"),document.getElementById("__notebook-source").classList.toggle("hidden")})),document.getElementById("__notebook-submit").addEventListener("click",n(t().mark((function e(){var n,o;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return n=document.getElementById("__notebook-render"),s=document.getElementById("__notebook-input").value,n.classList.toggle("hidden"),document.getElementById("__notebook-source").classList.toggle("hidden"),o=document.querySelector("article"),S(o,"Loading Notebook..."),n.innerHTML="",c={},t.next=10,L(!0);case 10:return t.next=12,k(s);case 12:return t.next=14,B();case 14:A(o),w();case 16:case"end":return t.stop()}}),e)}))))}d.addEventListener("touchmove",(function(t){t.stopPropagation()})),p.addEventListener("click",(function(t){var e=t.target;if(e.matches("span.swatch-color")){var n="",o=e.parentNode;if(!o.matches("span.swatch-gradient")){if(n=(n=o.getAttribute("title").replace("Copy to clipboard","")).replace("\n",""),window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",n);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){var r=document.createElement("textarea");r.textContent=n,r.style.position="fixed",document.body.appendChild(r),r.select();try{return document.execCommand("copy")}catch(t){return prompt("Copy to clipboard: Ctrl+C, Enter",n)}finally{document.body.removeChild(r)}}}}})),m.addEventListener("click",n(t().mark((function e(){return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:c[a]=d.value,f.classList.toggle("hidden"),p.classList.toggle("hidden"),h.classList.toggle("hidden"),_.classList.toggle("hidden"),m.classList.toggle("hidden"),g.classList.toggle("hidden"),x(d),d.focus();case 9:case"end":return t.stop()}}),e)})))),g.addEventListener("click",n(t().mark((function e(){var o,r,a,i,s;return t().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:o=window.location.pathname.split("/")[1],r=b(d.value),a=window.location,i="/playground/",a.pathname.startsWith("/".concat(o,"/"))&&(i="/".concat(o,"/playground/")),(s="".concat(a.protocol,"//").concat(a.host).concat(i,"?code=").concat(r)).length>2e3?alert("Code must be small enough to generate a shareable URL under 2000 characters!"):navigator.clipboard.writeText(s).then(n(t().mark((function e(){return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:alert("Link copied to clipboard :)");case 1:case"end":return t.stop()}}),e)}))),n(t().mark((function e(){return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:alert("Failed to copy link clipboard!");case 1:case"end":return t.stop()}}),e)}))));case 7:case"end":return e.stop()}}),e)})))),h.addEventListener("click",n(t().mark((function e(){var n,o;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(!i){t.next=2;break}return t.abrupt("return");case 2:return i=!0,n=f.querySelector("form"),S(n,null,!0),(o=document.querySelectorAll(".playground .playground-run"))&&o.forEach((function(t){t.setAttribute("disabled","")})),t.next=9,L(!1);case 9:return p.querySelector("code").innerHTML="",t.next=12,E(a);case 12:o&&o.forEach((function(t){t.removeAttribute("disabled")})),A(n),f.classList.toggle("hidden"),p.classList.toggle("hidden"),m.classList.toggle("hidden"),g.classList.toggle("hidden"),h.classList.toggle("hidden"),_.classList.toggle("hidden"),delete c[a],i=!1;case 22:case"end":return t.stop()}}),e)})))),_.addEventListener("click",(function(){d.value=c[a],delete c[a],f.classList.toggle("hidden"),p.classList.toggle("hidden"),m.classList.toggle("hidden"),g.classList.toggle("hidden"),h.classList.toggle("hidden"),_.classList.toggle("hidden")}))}));case 3:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),I=function(){var e=n(t().mark((function e(o,r){var a,i,s,u,d,f,m,g,y;return t().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(c={},!window.location.pathname.endsWith("/playground/")){e.next=32;break}if(a=r||new URLSearchParams(window.location.search),i="Loading Pyodide...",s="Loading Notebook...",u=a.has("source")?a.get("source"):a.get("notebook"),d=document.querySelector("article"),null===u||!u.trim()){e.next=16;break}return S(d,i),e.next=11,L(!0);case 11:A(d),S(d,s);try{f=a.has("source")?"source":"notebook",p=decodeURIComponent(a.toString()),m="",g=new XMLHttpRequest,l=u,g.open("GET",u,!0),g.onload=n(t().mark((function e(){return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return 4===g.readyState&&200===g.status&&(m=g.responseText),"source"===f&&(m=_(m)),t.next=4,k(m);case 4:return t.next=6,B(o);case 6:A(d),w();case 8:case"end":return t.stop()}}),e)}))),g.send()}catch(t){}e.next=30;break;case 16:return l="",y=_(a.has("code")?a.get("code"):h),p=decodeURIComponent(a.toString()),S(d,i),e.next=22,L(!0);case 22:return A(d),S(d,s),e.next=26,k(y);case 26:return e.next=28,B(o);case 28:A(d),w();case 30:e.next=35;break;case 32:l="",p="",B(o);case 35:case"end":return e.stop()}}),e)})));return function(t,n){return e.apply(this,arguments)}}();document.addEventListener("click",(function(t){var e=window.location.pathname.split("/")[1],n=t.target||t.srcElement;if("A"===n.tagName&&I&&n.getAttribute("href")&&n.host===window.location.host&&window.location.pathname==="/".concat(e,"/playground/")&&window.location.pathname===n.pathname&&window.location.search!==n.search){t.preventDefault();var o=new URLSearchParams(n.search);I(!1,o)}}),!0),window.addEventListener("popstate",(function(){var t=window.location.pathname.split("/")[1];window.location.pathname==="/".concat(t,"/playground/")&&(decodeURIComponent(new URLSearchParams(window.location.search).toString())!==p&&I(!1))})),window.addEventListener("unload",(function(){f=!1})),window.document$.subscribe((function(){f?f=!1:I(!0)}))}()}();
+//# sourceMappingURL=extra-notebook-b5858b87.js.map
diff --git a/docs/theme/assets/coloraide-extras/extra-notebook-3d99782d.js.map b/docs/theme/assets/coloraide-extras/extra-notebook-b5858b87.js.map
similarity index 99%
rename from docs/theme/assets/coloraide-extras/extra-notebook-3d99782d.js.map
rename to docs/theme/assets/coloraide-extras/extra-notebook-b5858b87.js.map
index c59d3e4e7..1017f41b5 100644
--- a/docs/theme/assets/coloraide-extras/extra-notebook-3d99782d.js.map
+++ b/docs/theme/assets/coloraide-extras/extra-notebook-b5858b87.js.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"extra-notebook-3d99782d.js","sources":["extra-notebook.js"],"sourcesContent":["(() => {\n  let webspace = ''\n  try {\n    let gamut = 'srgb'\n    if (window.matchMedia(\"(color-gamut: rec2020)\").matches) {\n      gamut = 'rec2020'\n    } else if (window.matchMedia(\"(color-gamut: p3)\").matches) {\n      gamut = 'display-p3'\n    }\n    webspace = (CSS.supports('color: color(display-p3 1 0 0)')) ? gamut : 'srgb'\n  } catch {\n    webspace = 'srgb'\n  }\n  let pyodide = null\n  let busy = false\n  let raw = \"\"\n  let gist = \"\"\n  let editTemp = {}\n  const reIdNum = /.*?_(\\d+)$/\n  let initialized = false\n  let lastSearch = \"\"\n  let fake = false\n  const tabStart = /^( {1,4}|\\t)/\n  // This is the Python payload that will be executed when the user\n  // presses the `Run` button. It will execute the code, create a\n  // Python console output, find color references, steps, and interpolation\n  // references and render the appropriate preview.\n  const pycode = `\n{{pycode}}\n\naction = globals().get('action')\nif action == 'notebook':\n    callback = render_notebook\nelse:\n    callback = render_console\n\ncallback(gamut='${webspace}')\n`\n\n  const defContent = window.colorNotebook.defaultPlayground\n\n  const getContent = content => {\n    return `\n/// new | This notebook is powered by [Pyodide](https://github.com/pyodide/pyodide). \\\nLearn more [here](\\\n?notebook=https://gist.githubusercontent.com/facelessuser/7c819668b5eb248ecb9ac608d91391cf/raw/playground.md\\\n). Preview, convert, interpolate, and explore!\n///\n\n\\`\\`\\`\\`\\`\\`\\`\\`py play\n${content}\n\\`\\`\\`\\`\\`\\`\\`\\`\n`\n  }\n\n  let notebookInstalled = false\n  let playgroundInstalled = false\n\n  const fakeDOMContentLoaded = () => {\n    // Send a fake `DOMContentLoaded`\n    fake = true\n    window.document.dispatchEvent(new Event(\"DOMContentLoaded\", {\n      bubbles: true,\n      cancelable: true\n    }))\n    window.document$.next()\n  }\n\n  const textResize = inpt => {\n    // Resize inputs based on text height.\n\n    const scrollLeft = window.pageXOffset ||\n      (document.documentElement || document.body.parentNode || document.body).scrollLeft\n\n    const scrollTop  = window.pageYOffset ||\n      (document.documentElement || document.body.parentNode || document.body).scrollTop\n\n    inpt.style.height = \"5px\"\n    inpt.style.height = `${inpt.scrollHeight}px`\n\n    window.scrollTo(scrollLeft, scrollTop)\n  }\n\n  const encodeuri = uri => {\n    // Encode the URI component.\n\n    return encodeURIComponent(uri).replace(/[.!'()*]/g, c => {\n      return `%${c.charCodeAt(0).toString(16)}`\n    })\n  }\n\n  const pyexecute = async currentID => {\n    // Execute Python code inside a playground\n\n    const currentInputs = document.getElementById(`__playground-inputs_${currentID}`)\n    currentInputs.setAttribute(\"readonly\", \"\")\n    pyodide.globals.set(\"id_num\", currentID)\n    pyodide.globals.set(\"action\", \"playground\")\n    await pyodide.runPythonAsync(pycode)\n    currentInputs.removeAttribute(\"readonly\")\n  }\n\n  const pyrender = async text => {\n    // Render an entire notebook page\n\n    pyodide.globals.set(\"content\", text)\n    pyodide.globals.set(\"action\", \"notebook\")\n    await pyodide.runPythonAsync(pycode)\n    const src = document.getElementById(\"__notebook-input\")\n    if (src) {\n      raw = text\n      src.value = text\n    }\n    if (window.location.hash) {\n      // Force jumping to hashes\n      window.location.href = window.location.href // eslint-disable-line no-self-assign\n    }\n  }\n\n  const setupPyodide = async full => {\n    // Load `Pyodide` and the any default packages we can need and can load.\n\n    if (!initialized) {\n      initialized = true\n      pyodide = await loadPyodide({ // eslint-disable-line no-undef\n        indexURL: \"https://cdn.jsdelivr.net/pyodide/v0.23.0/full/\",\n        fullStdLib: false\n      })\n    }\n\n    if ((!notebookInstalled && full) || (!playgroundInstalled && !full)) {\n      const base = `${window.location.origin}/${window.location.pathname.split('/')[1]}/playground/`\n      const packages = (full) ? window.colorNotebook.notebookWheels : window.colorNotebook.playgroundWheels\n      const installs = []\n      if (full) {\n        notebookInstalled = true\n      } else {\n        playgroundInstalled = true\n      }\n      for (const s of packages) {\n        if (s.endsWith('.whl')) {\n          installs.push(base + s)\n        } else {\n          installs.push(s)\n        }\n      }\n      await pyodide.loadPackage(installs)\n    }\n  }\n\n  const showBusy = (target, label, relative) => {\n    // Show busy indicator\n\n    const loaderLabel = (typeof label === \"undefined\" || label === null) ? \"Loading...\" : label\n    const classes = relative ? \"loading relative\" : \"loading\"\n    const template = document.createElement(\"template\")\n    template.innerHTML = `<div class=\"${classes}\"><div class=\"loader\"></div><div>${loaderLabel}</div></div>`\n    target.appendChild(template.content.firstChild)\n  }\n\n  const hideBusy = target => {\n    // Hide busy indicator\n\n    const loading = target.querySelector(\".loading\")\n    if (loading) {\n      target.removeChild(target.querySelector(\".loading\"))\n    }\n  }\n\n  const popState = () => {\n    // Handle notebook history\n\n    const base = window.location.pathname.split('/')[1]\n    if (\n      window.location.pathname === `/${base}/playground/`\n    ) {\n      const current = decodeURIComponent(new URLSearchParams(window.location.search).toString())\n      if (current !== lastSearch) {\n        main(false) // eslint-disable-line no-use-before-define\n      }\n    }\n  }\n\n  const interceptClickEvent = e => {\n    // Catch links to other notebook pages and handle them\n\n    const base = window.location.pathname.split('/')[1]\n    const target = e.target || e.srcElement\n    if (target.tagName === \"A\" && main) { // eslint-disable-line no-use-before-define\n      if (\n        target.getAttribute(\"href\") &&\n        target.host === window.location.host &&\n        window.location.pathname === `/${base}/playground/` &&\n        window.location.pathname === target.pathname &&\n        window.location.search !== target.search\n      ) {\n        e.preventDefault()\n        const search = new URLSearchParams(target.search)\n        main(false, search) // eslint-disable-line no-use-before-define\n      }\n    }\n  }\n\n  const handleTab = e => {\n    // Prevent tab from tabbing out.\n\n    if (e.key === 'Tab') {\n      const target = e.target\n\n      if (target.selectionStart !== target.selectionEnd) {\n        e.preventDefault()\n\n        let start = target.selectionStart\n        let end = target.selectionEnd\n\n        const text = target.value\n\n        while (start > 0 && text[start - 1] !== '\\n') {\n          start--\n        }\n        while (end > 0 && text[end - 1] !== '\\n' && end < text.length) {\n          end++\n        }\n\n        let lines = text.substr(start, end - start).split('\\n')\n\n        for (let i = 0; i < lines.length; i++) {\n\n          // Don't indent last line if cursor at start of line\n          if (i === lines.length - 1 && lines[i].length === 0) {\n            continue\n          }\n\n          // Indent or deindent\n          if (e.shiftKey) {\n            lines[i] = lines[i].replace(tabStart, '')\n          } else {\n            lines[i] = `    ${lines[i]}`\n          }\n        }\n        lines = lines.join('\\n')\n\n        // Update the text area\n        target.value = text.substr(0, start) + lines + text.substr(end)\n        target.selectionStart = start\n        target.selectionEnd = start + lines.length\n      }\n    }\n  }\n\n  const init = async first => {\n    // Setup input highlighting and events to run Python code blocks.\n\n    const notebook = document.getElementById(\"__notebook-source\")\n    const playgrounds = document.querySelectorAll(\".playground\")\n    playgrounds.forEach(pg => {\n\n      const currentID = pg.id.replace(reIdNum, \"$1\")\n      const inputs = document.getElementById(`__playground-inputs_${currentID}`)\n      const results = document.getElementById(`__playground-results_${currentID}`)\n      const pgcode = document.getElementById(`__playground-code_${currentID}`)\n      const buttonEdit = document.querySelector(`button#__playground-edit_${currentID}`)\n      const buttonShare = document.querySelector(`button#__playground-share_${currentID}`)\n      const buttonRun = document.querySelector(`button#__playground-run_${currentID}`)\n      const buttonCancel = document.querySelector(`button#__playground-cancel_${currentID}`)\n\n      inputs.addEventListener(\"input\", () => {\n        // Adjust textarea height on text input.\n\n        textResize(inputs)\n      })\n\n      inputs.addEventListener('keydown', handleTab)\n\n      if (notebook && first) {\n        const notebookInput = document.getElementById(\"__notebook-input\")\n\n        notebookInput.addEventListener(\"input\", e => {\n          // Adjust textarea height on text input.\n\n          textResize(e.target)\n        })\n\n        notebookInput.addEventListener('keydown', handleTab)\n\n        const editPage = document.getElementById(\"__notebook-edit\")\n        editPage.addEventListener(\"click\", () => {\n          editTemp[notebookInput.id] = notebookInput.value\n          document.getElementById(\"__notebook-render\").classList.toggle(\"hidden\")\n          document.getElementById(\"__notebook-source\").classList.toggle(\"hidden\")\n          textResize(document.getElementById(\"__notebook-input\"))\n        })\n\n        document.getElementById(\"__notebook-md-gist\").addEventListener(\"click\", async e => {\n          let uri = prompt(\"Please enter link to the Markdown page source:\", gist) // eslint-disable-line no-alert\n          if (uri !== null) {\n            uri = encodeuri(uri)\n            e.preventDefault()\n            history.pushState({notebook: uri}, \"\", `?${new URLSearchParams(`notebook=${uri}`).toString()}`)\n            main(false) // eslint-disable-line no-use-before-define\n          }\n        })\n\n        document.getElementById(\"__notebook-py-gist\").addEventListener(\"click\", async e => {\n          let uri = prompt(\"Please enter the link to the Python code source:\", gist) // eslint-disable-line no-alert\n          if (uri !== null) {\n            uri = encodeuri(uri)\n            e.preventDefault()\n            history.pushState({source: uri}, \"\", `?${new URLSearchParams(`source=${uri}`).toString()}`)\n            main(false) // eslint-disable-line no-use-before-define\n          }\n        })\n\n        document.getElementById(\"__notebook-input\").value = raw\n        document.getElementById(\"__notebook-cancel\").addEventListener(\"click\", () => {\n          notebookInput.value = editTemp[notebookInput.id]\n          delete editTemp[notebookInput.id]\n          document.getElementById(\"__notebook-render\").classList.toggle(\"hidden\")\n          document.getElementById(\"__notebook-source\").classList.toggle(\"hidden\")\n        })\n\n        document.getElementById(\"__notebook-submit\").addEventListener(\"click\", async() => {\n          const render = document.getElementById(\"__notebook-render\")\n          raw = document.getElementById(\"__notebook-input\").value\n          render.classList.toggle(\"hidden\")\n          document.getElementById(\"__notebook-source\").classList.toggle(\"hidden\")\n          const article = document.querySelector(\"article\")\n          showBusy(article, \"Loading Notebook...\")\n          render.innerHTML = \"\"\n          editTemp = {}\n          await setupPyodide(true)\n          await pyrender(raw)\n          await init()\n          hideBusy(article)\n          fakeDOMContentLoaded()\n        })\n      }\n\n      inputs.addEventListener(\"touchmove\", e => {\n        // Stop propagation on \"touchmove\".\n\n        e.stopPropagation()\n      })\n\n      results.addEventListener(\"click\", e => {\n        // Handle clicks on results and copies color from single color swatch when clicked.\n\n        const el = e.target\n        if (el.matches('span.swatch-color')) {\n          let content = ''\n          const parent = el.parentNode\n          if (!parent.matches('span.swatch-gradient')) {\n            content = parent.getAttribute('title').replace('Copy to clipboard', '')\n            content = content.replace('\\n', '')\n            if (window.clipboardData && window.clipboardData.setData) {\n              // Old `IE`` handling, do we really need this?\n              return window.clipboardData.setData(\"Text\", content)\n            } else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n              const textarea = document.createElement(\"textarea\")\n              textarea.textContent = content\n              textarea.style.position = \"fixed\"\n              document.body.appendChild(textarea)\n              textarea.select()\n              try {\n                return document.execCommand(\"copy\")\n              } catch (ex) {\n                return prompt(\"Copy to clipboard: Ctrl+C, Enter\", content) // eslint-disable-line no-alert\n              } finally {\n                document.body.removeChild(textarea)\n              }\n            }\n          }\n        }\n      })\n\n      buttonEdit.addEventListener(\"click\", async() => {\n        // Handle the button click: show source or execute source.\n\n        editTemp[currentID] = inputs.value\n        pgcode.classList.toggle(\"hidden\")\n        results.classList.toggle(\"hidden\")\n        buttonRun.classList.toggle(\"hidden\")\n        buttonCancel.classList.toggle(\"hidden\")\n        buttonEdit.classList.toggle(\"hidden\")\n        buttonShare.classList.toggle(\"hidden\")\n        textResize(inputs)\n        inputs.focus()\n      })\n\n      buttonShare.addEventListener(\"click\", async() => {\n        // Handle the share click: copy URL with code as parameter.\n\n        const base = window.location.pathname.split('/')[1]\n        const uri = encodeuri(inputs.value)\n        const loc = window.location\n        let pathname = \"/playground/\"\n        if (loc.pathname.startsWith(`/${base}/`)) {\n          pathname = `/${base}/playground/`\n        }\n        const path = `${loc.protocol}//${loc.host}${pathname}?code=${uri}`\n        if (path.length > 2000) {\n          alert( // eslint-disable-line no-alert\n            \"Code must be small enough to generate a shareable URL under 2000 characters!\"\n          )\n        } else {\n          navigator.clipboard.writeText(path).then(async() => {\n            alert(\"Link copied to clipboard :)\") // eslint-disable-line no-alert\n          }, async() => {\n            alert(\"Failed to copy link clipboard!\") // eslint-disable-line no-alert\n          })\n        }\n      })\n\n      buttonRun.addEventListener(\"click\", async() => {\n        // Handle the button click: show source or execute source.\n\n        if (busy) {\n          return\n        }\n\n        busy = true\n        // Load Pyodide and related packages.\n        const form = pgcode.querySelector(\"form\")\n        showBusy(form, null, true)\n        const buttons = document.querySelectorAll(\".playground .playground-run\")\n        if (buttons) {\n          buttons.forEach(b => {\n            b.setAttribute(\"disabled\", \"\")\n          })\n        }\n        await setupPyodide(false)\n        results.querySelector(\"code\").innerHTML = \"\"\n        await pyexecute(currentID)\n        if (buttons) {\n          buttons.forEach(b => {\n            b.removeAttribute(\"disabled\")\n          })\n        }\n        hideBusy(form)\n        pgcode.classList.toggle(\"hidden\")\n        results.classList.toggle(\"hidden\")\n        buttonEdit.classList.toggle(\"hidden\")\n        buttonShare.classList.toggle(\"hidden\")\n        buttonRun.classList.toggle(\"hidden\")\n        buttonCancel.classList.toggle(\"hidden\")\n\n        delete editTemp[currentID]\n        busy = false\n      })\n\n      buttonCancel.addEventListener(\"click\", () => {\n        // Cancel edit.\n\n        inputs.value = editTemp[currentID]\n        delete editTemp[currentID]\n        pgcode.classList.toggle(\"hidden\")\n        results.classList.toggle(\"hidden\")\n        buttonEdit.classList.toggle(\"hidden\")\n        buttonShare.classList.toggle(\"hidden\")\n        buttonRun.classList.toggle(\"hidden\")\n        buttonCancel.classList.toggle(\"hidden\")\n      })\n    })\n  }\n\n  const main = async(first, search) => {\n    // Load external source to render in a playground.\n    // This can be something like a file on a gist we must read in (?source=)\n    // or raw code (?code=).\n\n    editTemp = {}\n\n    if (window.location.pathname.endsWith(\"/playground/\")) {\n      const params = search || new URLSearchParams(window.location.search)\n      const loadMsg = \"Loading Pyodide...\"\n      const pageMsg = \"Loading Notebook...\"\n      const uri = params.has(\"source\") ? params.get(\"source\") : params.get(\"notebook\")\n      const article = document.querySelector(\"article\")\n      if (uri !== null && uri.trim()) {\n        // A source was specified, so load it.\n        showBusy(article, loadMsg)\n        await setupPyodide(true)\n        hideBusy(article)\n        showBusy(article, pageMsg)\n        try {\n          const gistType = params.has(\"source\") ? \"source\" : \"notebook\"\n          lastSearch = decodeURIComponent(params.toString())\n          let value = \"\"\n          const xhr = new XMLHttpRequest()\n          gist = uri\n          xhr.open(\"GET\", uri, true)\n          xhr.onload = async() => {\n            // Try and load the requested content\n            if (xhr.readyState === 4) {\n              if (xhr.status === 200) {\n                value = xhr.responseText\n              }\n            }\n\n            if (gistType === \"source\") {\n              value = getContent(value)\n            }\n            await pyrender(value)\n            await init(first)\n            hideBusy(article)\n            fakeDOMContentLoaded()\n          }\n          xhr.send()\n        } catch (err) {} // eslint-disable-line no-empty\n      } else {\n        gist = \"\"\n        const content = getContent(params.has(\"code\") ? params.get(\"code\") : defContent)\n        lastSearch = decodeURIComponent(params.toString())\n        showBusy(article, loadMsg)\n        await setupPyodide(true)\n        hideBusy(article)\n        showBusy(article, pageMsg)\n        await pyrender(content)\n        await init(first)\n        hideBusy(article)\n        fakeDOMContentLoaded()\n      }\n    } else {\n      gist = \"\"\n      lastSearch = \"\"\n      init(first)\n    }\n  }\n\n  // Capture links in notebook pages so that we can make playgound links load instantly\n  document.addEventListener(\"click\", interceptClickEvent, true)\n\n  // Handle history of notebook pages as they are loaded dynamically\n  window.addEventListener(\"popstate\", popState)\n\n  // Before leaving, turn off fake, just in case we navigated away before finished\n  window.addEventListener(\"unload\", () => {\n    fake = false\n  })\n\n  // Attach main via subscribe (subscribes to Materials on page load and instant page loads)\n  window.document$.subscribe(() => {\n    // To get other libraries to reload, we may create a fake `DOMContentLoaded`\n    // No need to process these events.\n    if (fake) {\n      fake = false\n      return\n    }\n    main(true)\n  })\n})()\n"],"names":["webspace","gamut","window","matchMedia","matches","CSS","supports","_unused","pyodide","busy","raw","gist","editTemp","reIdNum","initialized","lastSearch","fake","tabStart","pycode","concat","defContent","colorNotebook","defaultPlayground","getContent","content","notebookInstalled","playgroundInstalled","fakeDOMContentLoaded","document","dispatchEvent","Event","bubbles","cancelable","document$","next","textResize","inpt","scrollLeft","pageXOffset","documentElement","body","parentNode","scrollTop","pageYOffset","style","height","scrollHeight","scrollTo","encodeuri","uri","encodeURIComponent","replace","c","charCodeAt","toString","pyexecute","_ref","_asyncToGenerator","_regeneratorRuntime","mark","_callee","currentID","currentInputs","wrap","_context","prev","getElementById","setAttribute","globals","set","runPythonAsync","removeAttribute","stop","_x","apply","this","arguments","pyrender","_ref2","_callee2","text","src","_context2","value","location","hash","href","_x2","setupPyodide","_ref3","_callee3","full","base","packages","installs","_iterator","_step","s","_context3","loadPyodide","indexURL","fullStdLib","sent","origin","pathname","split","notebookWheels","playgroundWheels","_createForOfIteratorHelper","n","done","endsWith","push","err","e","f","loadPackage","_x3","showBusy","target","label","relative","loaderLabel","classes","template","createElement","innerHTML","appendChild","firstChild","hideBusy","querySelector","removeChild","handleTab","key","selectionStart","selectionEnd","preventDefault","start","end","length","lines","substr","i","shiftKey","join","init","_ref4","_callee12","first","notebook","_context12","querySelectorAll","forEach","pg","id","inputs","results","pgcode","buttonEdit","buttonShare","buttonRun","buttonCancel","addEventListener","notebookInput","classList","toggle","_ref5","_callee4","_context4","prompt","history","pushState","URLSearchParams","main","_x5","_ref6","_callee5","_context5","source","_x6","_callee6","render","article","_context6","stopPropagation","el","parent","getAttribute","clipboardData","setData","queryCommandSupported","textarea","textContent","position","select","execCommand","ex","_callee7","_context7","focus","_callee10","loc","path","_context10","startsWith","protocol","host","alert","navigator","clipboard","writeText","then","_callee8","_context8","_callee9","_context9","_callee11","form","buttons","_context11","abrupt","b","_x4","_ref13","_callee14","search","params","loadMsg","pageMsg","gistType","xhr","_context14","has","get","trim","decodeURIComponent","XMLHttpRequest","open","onload","_callee13","_context13","readyState","status","responseText","send","_x7","_x8","srcElement","tagName","subscribe"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"extra-notebook-b5858b87.js","sources":["extra-notebook.js"],"sourcesContent":["(() => {\n  let webspace = ''\n  try {\n    let gamut = 'srgb'\n    if (window.matchMedia(\"(color-gamut: rec2020)\").matches) {\n      gamut = 'rec2020'\n    } else if (window.matchMedia(\"(color-gamut: p3)\").matches) {\n      gamut = 'display-p3'\n    }\n    webspace = (CSS.supports('color: color(display-p3 1 0 0)')) ? gamut : 'srgb'\n  } catch {\n    webspace = 'srgb'\n  }\n  let pyodide = null\n  let busy = false\n  let raw = \"\"\n  let gist = \"\"\n  let editTemp = {}\n  const reIdNum = /.*?_(\\d+)$/\n  let initialized = false\n  let lastSearch = \"\"\n  let fake = false\n  const tabStart = /^( {1,4}|\\t)/\n  // This is the Python payload that will be executed when the user\n  // presses the `Run` button. It will execute the code, create a\n  // Python console output, find color references, steps, and interpolation\n  // references and render the appropriate preview.\n  const pycode = `\n{{pycode}}\n\naction = globals().get('action')\nif action == 'notebook':\n    callback = render_notebook\nelse:\n    callback = render_console\n\ncallback(gamut='${webspace}')\n`\n\n  const defContent = window.colorNotebook.defaultPlayground\n\n  const getContent = content => {\n    return `\n/// new | This notebook is powered by [Pyodide](https://github.com/pyodide/pyodide). \\\nLearn more [here](\\\n?notebook=https://gist.githubusercontent.com/facelessuser/7c819668b5eb248ecb9ac608d91391cf/raw/playground.md\\\n). Preview, convert, interpolate, and explore!\n///\n\n\\`\\`\\`\\`\\`\\`\\`\\`py play\n${content}\n\\`\\`\\`\\`\\`\\`\\`\\`\n`\n  }\n\n  let notebookInstalled = false\n  let playgroundInstalled = false\n\n  const fakeDOMContentLoaded = () => {\n    // Send a fake `DOMContentLoaded`\n    fake = true\n    window.document.dispatchEvent(new Event(\"DOMContentLoaded\", {\n      bubbles: true,\n      cancelable: true\n    }))\n    window.document$.next()\n  }\n\n  const textResize = inpt => {\n    // Resize inputs based on text height.\n\n    const scrollLeft = window.pageXOffset ||\n      (document.documentElement || document.body.parentNode || document.body).scrollLeft\n\n    const scrollTop  = window.pageYOffset ||\n      (document.documentElement || document.body.parentNode || document.body).scrollTop\n\n    inpt.style.height = \"5px\"\n    inpt.style.height = `${inpt.scrollHeight}px`\n\n    window.scrollTo(scrollLeft, scrollTop)\n  }\n\n  const encodeuri = uri => {\n    // Encode the URI component.\n\n    return encodeURIComponent(uri).replace(/[.!'()*]/g, c => {\n      return `%${c.charCodeAt(0).toString(16)}`\n    })\n  }\n\n  const pyexecute = async currentID => {\n    // Execute Python code inside a playground\n\n    const currentInputs = document.getElementById(`__playground-inputs_${currentID}`)\n    currentInputs.setAttribute(\"readonly\", \"\")\n    pyodide.globals.set(\"id_num\", currentID)\n    pyodide.globals.set(\"action\", \"playground\")\n    await pyodide.runPythonAsync(pycode)\n    currentInputs.removeAttribute(\"readonly\")\n  }\n\n  const pyrender = async text => {\n    // Render an entire notebook page\n\n    pyodide.globals.set(\"content\", text)\n    pyodide.globals.set(\"action\", \"notebook\")\n    await pyodide.runPythonAsync(pycode)\n    const src = document.getElementById(\"__notebook-input\")\n    if (src) {\n      raw = text\n      src.value = text\n    }\n    if (window.location.hash) {\n      // Force jumping to hashes\n      window.location.href = window.location.href // eslint-disable-line no-self-assign\n    }\n  }\n\n  const setupPyodide = async full => {\n    // Load `Pyodide` and the any default packages we can need and can load.\n\n    if (!initialized) {\n      initialized = true\n      pyodide = await loadPyodide({ // eslint-disable-line no-undef\n        indexURL: \"https://cdn.jsdelivr.net/pyodide/v0.23.0/full/\",\n        fullStdLib: false\n      })\n    }\n\n    if ((!notebookInstalled && full) || (!playgroundInstalled && !full)) {\n      const base = `${window.location.origin}/${window.location.pathname.split('/')[1]}/playground/`\n      const packages = (full) ? window.colorNotebook.notebookWheels : window.colorNotebook.playgroundWheels\n      const installs = []\n      if (full) {\n        notebookInstalled = true\n      } else {\n        playgroundInstalled = true\n      }\n      for (const s of packages) {\n        if (s.endsWith('.whl')) {\n          installs.push(base + s)\n        } else {\n          installs.push(s)\n        }\n      }\n      await pyodide.loadPackage(installs)\n    }\n  }\n\n  const showBusy = (target, label, relative) => {\n    // Show busy indicator\n\n    const loaderLabel = (typeof label === \"undefined\" || label === null) ? \"Loading...\" : label\n    const classes = relative ? \"loading relative\" : \"loading\"\n    const template = document.createElement(\"template\")\n    template.innerHTML = `<div class=\"${classes}\"><div class=\"loader\"></div><div>${loaderLabel}</div></div>`\n    target.appendChild(template.content.firstChild)\n  }\n\n  const hideBusy = target => {\n    // Hide busy indicator\n\n    const loading = target.querySelector(\".loading\")\n    if (loading) {\n      target.removeChild(target.querySelector(\".loading\"))\n    }\n  }\n\n  const popState = () => {\n    // Handle notebook history\n\n    const base = window.location.pathname.split('/')[1]\n    if (\n      window.location.pathname === `/${base}/playground/`\n    ) {\n      const current = decodeURIComponent(new URLSearchParams(window.location.search).toString())\n      if (current !== lastSearch) {\n        main(false) // eslint-disable-line no-use-before-define\n      }\n    }\n  }\n\n  const interceptClickEvent = e => {\n    // Catch links to other notebook pages and handle them\n\n    const base = window.location.pathname.split('/')[1]\n    const target = e.target || e.srcElement\n    if (target.tagName === \"A\" && main) { // eslint-disable-line no-use-before-define\n      if (\n        target.getAttribute(\"href\") &&\n        target.host === window.location.host &&\n        window.location.pathname === `/${base}/playground/` &&\n        window.location.pathname === target.pathname &&\n        window.location.search !== target.search\n      ) {\n        e.preventDefault()\n        const search = new URLSearchParams(target.search)\n        main(false, search) // eslint-disable-line no-use-before-define\n      }\n    }\n  }\n\n  const handleTab = e => {\n    // Prevent tab from tabbing out.\n\n    if (e.key === 'Tab') {\n      const target = e.target\n\n      if (target.selectionStart !== target.selectionEnd) {\n        e.preventDefault()\n\n        let start = target.selectionStart\n        let end = target.selectionEnd\n\n        const text = target.value\n\n        while (start > 0 && text[start - 1] !== '\\n') {\n          start--\n        }\n        while (end > 0 && text[end - 1] !== '\\n' && end < text.length) {\n          end++\n        }\n\n        let lines = text.substr(start, end - start).split('\\n')\n\n        for (let i = 0; i < lines.length; i++) {\n\n          // Don't indent last line if cursor at start of line\n          if (i === lines.length - 1 && lines[i].length === 0) {\n            continue\n          }\n\n          // Indent or deindent\n          if (e.shiftKey) {\n            lines[i] = lines[i].replace(tabStart, '')\n          } else {\n            lines[i] = `    ${lines[i]}`\n          }\n        }\n        lines = lines.join('\\n')\n\n        // Update the text area\n        target.value = text.substr(0, start) + lines + text.substr(end)\n        target.selectionStart = start\n        target.selectionEnd = start + lines.length\n      }\n    }\n  }\n\n  const init = async first => {\n    // Setup input highlighting and events to run Python code blocks.\n\n    const notebook = document.getElementById(\"__notebook-source\")\n    const playgrounds = document.querySelectorAll(\".playground\")\n    playgrounds.forEach(pg => {\n\n      const currentID = pg.id.replace(reIdNum, \"$1\")\n      const inputs = document.getElementById(`__playground-inputs_${currentID}`)\n      const results = document.getElementById(`__playground-results_${currentID}`)\n      const pgcode = document.getElementById(`__playground-code_${currentID}`)\n      const buttonEdit = document.querySelector(`button#__playground-edit_${currentID}`)\n      const buttonShare = document.querySelector(`button#__playground-share_${currentID}`)\n      const buttonRun = document.querySelector(`button#__playground-run_${currentID}`)\n      const buttonCancel = document.querySelector(`button#__playground-cancel_${currentID}`)\n\n      inputs.addEventListener(\"input\", () => {\n        // Adjust textarea height on text input.\n\n        textResize(inputs)\n      })\n\n      inputs.addEventListener('keydown', handleTab)\n\n      if (notebook && first) {\n        const notebookInput = document.getElementById(\"__notebook-input\")\n\n        notebookInput.addEventListener(\"input\", e => {\n          // Adjust textarea height on text input.\n\n          textResize(e.target)\n        })\n\n        notebookInput.addEventListener('keydown', handleTab)\n\n        const editPage = document.getElementById(\"__notebook-edit\")\n        editPage.addEventListener(\"click\", () => {\n          editTemp[notebookInput.id] = notebookInput.value\n          document.getElementById(\"__notebook-render\").classList.toggle(\"hidden\")\n          document.getElementById(\"__notebook-source\").classList.toggle(\"hidden\")\n          textResize(document.getElementById(\"__notebook-input\"))\n        })\n\n        document.getElementById(\"__notebook-md-gist\").addEventListener(\"click\", async e => {\n          let uri = prompt(\"Please enter link to the Markdown page source:\", gist) // eslint-disable-line no-alert\n          if (uri !== null) {\n            uri = encodeuri(uri)\n            e.preventDefault()\n            history.pushState({notebook: uri}, \"\", `?${new URLSearchParams(`notebook=${uri}`).toString()}`)\n            main(false) // eslint-disable-line no-use-before-define\n          }\n        })\n\n        document.getElementById(\"__notebook-py-gist\").addEventListener(\"click\", async e => {\n          let uri = prompt(\"Please enter the link to the Python code source:\", gist) // eslint-disable-line no-alert\n          if (uri !== null) {\n            uri = encodeuri(uri)\n            e.preventDefault()\n            history.pushState({source: uri}, \"\", `?${new URLSearchParams(`source=${uri}`).toString()}`)\n            main(false) // eslint-disable-line no-use-before-define\n          }\n        })\n\n        document.getElementById(\"__notebook-input\").value = raw\n        document.getElementById(\"__notebook-cancel\").addEventListener(\"click\", () => {\n          notebookInput.value = editTemp[notebookInput.id]\n          delete editTemp[notebookInput.id]\n          document.getElementById(\"__notebook-render\").classList.toggle(\"hidden\")\n          document.getElementById(\"__notebook-source\").classList.toggle(\"hidden\")\n        })\n\n        document.getElementById(\"__notebook-submit\").addEventListener(\"click\", async() => {\n          const render = document.getElementById(\"__notebook-render\")\n          raw = document.getElementById(\"__notebook-input\").value\n          render.classList.toggle(\"hidden\")\n          document.getElementById(\"__notebook-source\").classList.toggle(\"hidden\")\n          const article = document.querySelector(\"article\")\n          showBusy(article, \"Loading Notebook...\")\n          render.innerHTML = \"\"\n          editTemp = {}\n          await setupPyodide(true)\n          await pyrender(raw)\n          await init()\n          hideBusy(article)\n          fakeDOMContentLoaded()\n        })\n      }\n\n      inputs.addEventListener(\"touchmove\", e => {\n        // Stop propagation on \"touchmove\".\n\n        e.stopPropagation()\n      })\n\n      results.addEventListener(\"click\", e => {\n        // Handle clicks on results and copies color from single color swatch when clicked.\n\n        const el = e.target\n        if (el.matches('span.swatch-color')) {\n          let content = ''\n          const parent = el.parentNode\n          if (!parent.matches('span.swatch-gradient')) {\n            content = parent.getAttribute('title').replace('Copy to clipboard', '')\n            content = content.replace('\\n', '')\n            if (window.clipboardData && window.clipboardData.setData) {\n              // Old `IE`` handling, do we really need this?\n              return window.clipboardData.setData(\"Text\", content)\n            } else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n              const textarea = document.createElement(\"textarea\")\n              textarea.textContent = content\n              textarea.style.position = \"fixed\"\n              document.body.appendChild(textarea)\n              textarea.select()\n              try {\n                return document.execCommand(\"copy\")\n              } catch (ex) {\n                return prompt(\"Copy to clipboard: Ctrl+C, Enter\", content) // eslint-disable-line no-alert\n              } finally {\n                document.body.removeChild(textarea)\n              }\n            }\n          }\n        }\n      })\n\n      buttonEdit.addEventListener(\"click\", async() => {\n        // Handle the button click: show source or execute source.\n\n        editTemp[currentID] = inputs.value\n        pgcode.classList.toggle(\"hidden\")\n        results.classList.toggle(\"hidden\")\n        buttonRun.classList.toggle(\"hidden\")\n        buttonCancel.classList.toggle(\"hidden\")\n        buttonEdit.classList.toggle(\"hidden\")\n        buttonShare.classList.toggle(\"hidden\")\n        textResize(inputs)\n        inputs.focus()\n      })\n\n      buttonShare.addEventListener(\"click\", async() => {\n        // Handle the share click: copy URL with code as parameter.\n\n        const base = window.location.pathname.split('/')[1]\n        const uri = encodeuri(inputs.value)\n        const loc = window.location\n        let pathname = \"/playground/\"\n        if (loc.pathname.startsWith(`/${base}/`)) {\n          pathname = `/${base}/playground/`\n        }\n        const path = `${loc.protocol}//${loc.host}${pathname}?code=${uri}`\n        if (path.length > 2000) {\n          alert( // eslint-disable-line no-alert\n            \"Code must be small enough to generate a shareable URL under 2000 characters!\"\n          )\n        } else {\n          navigator.clipboard.writeText(path).then(async() => {\n            alert(\"Link copied to clipboard :)\") // eslint-disable-line no-alert\n          }, async() => {\n            alert(\"Failed to copy link clipboard!\") // eslint-disable-line no-alert\n          })\n        }\n      })\n\n      buttonRun.addEventListener(\"click\", async() => {\n        // Handle the button click: show source or execute source.\n\n        if (busy) {\n          return\n        }\n\n        busy = true\n        // Load Pyodide and related packages.\n        const form = pgcode.querySelector(\"form\")\n        showBusy(form, null, true)\n        const buttons = document.querySelectorAll(\".playground .playground-run\")\n        if (buttons) {\n          buttons.forEach(b => {\n            b.setAttribute(\"disabled\", \"\")\n          })\n        }\n        await setupPyodide(false)\n        results.querySelector(\"code\").innerHTML = \"\"\n        await pyexecute(currentID)\n        if (buttons) {\n          buttons.forEach(b => {\n            b.removeAttribute(\"disabled\")\n          })\n        }\n        hideBusy(form)\n        pgcode.classList.toggle(\"hidden\")\n        results.classList.toggle(\"hidden\")\n        buttonEdit.classList.toggle(\"hidden\")\n        buttonShare.classList.toggle(\"hidden\")\n        buttonRun.classList.toggle(\"hidden\")\n        buttonCancel.classList.toggle(\"hidden\")\n\n        delete editTemp[currentID]\n        busy = false\n      })\n\n      buttonCancel.addEventListener(\"click\", () => {\n        // Cancel edit.\n\n        inputs.value = editTemp[currentID]\n        delete editTemp[currentID]\n        pgcode.classList.toggle(\"hidden\")\n        results.classList.toggle(\"hidden\")\n        buttonEdit.classList.toggle(\"hidden\")\n        buttonShare.classList.toggle(\"hidden\")\n        buttonRun.classList.toggle(\"hidden\")\n        buttonCancel.classList.toggle(\"hidden\")\n      })\n    })\n  }\n\n  const main = async(first, search) => {\n    // Load external source to render in a playground.\n    // This can be something like a file on a gist we must read in (?source=)\n    // or raw code (?code=).\n\n    editTemp = {}\n\n    if (window.location.pathname.endsWith(\"/playground/\")) {\n      const params = search || new URLSearchParams(window.location.search)\n      const loadMsg = \"Loading Pyodide...\"\n      const pageMsg = \"Loading Notebook...\"\n      const uri = params.has(\"source\") ? params.get(\"source\") : params.get(\"notebook\")\n      const article = document.querySelector(\"article\")\n      if (uri !== null && uri.trim()) {\n        // A source was specified, so load it.\n        showBusy(article, loadMsg)\n        await setupPyodide(true)\n        hideBusy(article)\n        showBusy(article, pageMsg)\n        try {\n          const gistType = params.has(\"source\") ? \"source\" : \"notebook\"\n          lastSearch = decodeURIComponent(params.toString())\n          let value = \"\"\n          const xhr = new XMLHttpRequest()\n          gist = uri\n          xhr.open(\"GET\", uri, true)\n          xhr.onload = async() => {\n            // Try and load the requested content\n            if (xhr.readyState === 4) {\n              if (xhr.status === 200) {\n                value = xhr.responseText\n              }\n            }\n\n            if (gistType === \"source\") {\n              value = getContent(value)\n            }\n            await pyrender(value)\n            await init(first)\n            hideBusy(article)\n            fakeDOMContentLoaded()\n          }\n          xhr.send()\n        } catch (err) {} // eslint-disable-line no-empty\n      } else {\n        gist = \"\"\n        const content = getContent(params.has(\"code\") ? params.get(\"code\") : defContent)\n        lastSearch = decodeURIComponent(params.toString())\n        showBusy(article, loadMsg)\n        await setupPyodide(true)\n        hideBusy(article)\n        showBusy(article, pageMsg)\n        await pyrender(content)\n        await init(first)\n        hideBusy(article)\n        fakeDOMContentLoaded()\n      }\n    } else {\n      gist = \"\"\n      lastSearch = \"\"\n      init(first)\n    }\n  }\n\n  // Capture links in notebook pages so that we can make playgound links load instantly\n  document.addEventListener(\"click\", interceptClickEvent, true)\n\n  // Handle history of notebook pages as they are loaded dynamically\n  window.addEventListener(\"popstate\", popState)\n\n  // Before leaving, turn off fake, just in case we navigated away before finished\n  window.addEventListener(\"unload\", () => {\n    fake = false\n  })\n\n  // Attach main via subscribe (subscribes to Materials on page load and instant page loads)\n  window.document$.subscribe(() => {\n    // To get other libraries to reload, we may create a fake `DOMContentLoaded`\n    // No need to process these events.\n    if (fake) {\n      fake = false\n      return\n    }\n    main(true)\n  })\n})()\n"],"names":["webspace","gamut","window","matchMedia","matches","CSS","supports","_unused","pyodide","busy","raw","gist","editTemp","reIdNum","initialized","lastSearch","fake","tabStart","pycode","concat","defContent","colorNotebook","defaultPlayground","getContent","content","notebookInstalled","playgroundInstalled","fakeDOMContentLoaded","document","dispatchEvent","Event","bubbles","cancelable","document$","next","textResize","inpt","scrollLeft","pageXOffset","documentElement","body","parentNode","scrollTop","pageYOffset","style","height","scrollHeight","scrollTo","encodeuri","uri","encodeURIComponent","replace","c","charCodeAt","toString","pyexecute","_ref","_asyncToGenerator","_regeneratorRuntime","mark","_callee","currentID","currentInputs","wrap","_context","prev","getElementById","setAttribute","globals","set","runPythonAsync","removeAttribute","stop","_x","apply","this","arguments","pyrender","_ref2","_callee2","text","src","_context2","value","location","hash","href","_x2","setupPyodide","_ref3","_callee3","full","base","packages","installs","_iterator","_step","s","_context3","loadPyodide","indexURL","fullStdLib","sent","origin","pathname","split","notebookWheels","playgroundWheels","_createForOfIteratorHelper","n","done","endsWith","push","err","e","f","loadPackage","_x3","showBusy","target","label","relative","loaderLabel","classes","template","createElement","innerHTML","appendChild","firstChild","hideBusy","querySelector","removeChild","handleTab","key","selectionStart","selectionEnd","preventDefault","start","end","length","lines","substr","i","shiftKey","join","init","_ref4","_callee12","first","notebook","_context12","querySelectorAll","forEach","pg","id","inputs","results","pgcode","buttonEdit","buttonShare","buttonRun","buttonCancel","addEventListener","notebookInput","classList","toggle","_ref5","_callee4","_context4","prompt","history","pushState","URLSearchParams","main","_x5","_ref6","_callee5","_context5","source","_x6","_callee6","render","article","_context6","stopPropagation","el","parent","getAttribute","clipboardData","setData","queryCommandSupported","textarea","textContent","position","select","execCommand","ex","_callee7","_context7","focus","_callee10","loc","path","_context10","startsWith","protocol","host","alert","navigator","clipboard","writeText","then","_callee8","_context8","_callee9","_context9","_callee11","form","buttons","_context11","abrupt","b","_x4","_ref13","_callee14","search","params","loadMsg","pageMsg","gistType","xhr","_context14","has","get","trim","decodeURIComponent","XMLHttpRequest","open","onload","_callee13","_context13","readyState","status","responseText","send","_x7","_x8","srcElement","tagName","subscribe"],"mappings":"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"}
\ No newline at end of file
diff --git a/mkdocs.yml b/mkdocs.yml
index 0dc413fed..7917eec58 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -98,6 +98,7 @@ nav:
         - CAM16 UCS: colors/cam16_ucs.md
         - CAM16 SCD: colors/cam16_scd.md
         - CAM16 LCD: colors/cam16_lcd.md
+        - XYB: colors/xyb.md
 
       - LCh Like Spaces:
         - LCh D50: colors/lch.md
@@ -269,7 +270,7 @@ extra_javascript:
   - https://unpkg.com/mermaid@8.13.3/dist/mermaid.min.js
   - playground-config-c8a475b3.js
   - https://cdn.jsdelivr.net/pyodide/v0.23.0/full/pyodide.js
-  - assets/coloraide-extras/extra-notebook-3d99782d.js
+  - assets/coloraide-extras/extra-notebook-b5858b87.js
 
 extra:
   social:
diff --git a/tools/gen_3d_models.py b/tools/gen_3d_models.py
index 1b7c8ef15..0d9184082 100644
--- a/tools/gen_3d_models.py
+++ b/tools/gen_3d_models.py
@@ -67,7 +67,8 @@ def plot_model(name, title, filename, gamut='srgb', elev=45, azim=-60.0):
     'cam16-jmh': {'title': TEMPLATE.format('CAM16 JMh'), 'filename': 'cam16-jmh-3d.png'},
     'hct': {'title': TEMPLATE.format('HCT'), 'filename': 'hct-3d.png'},
     'cmy': {'title': TEMPLATE.format('CMY'), 'filename': 'cmy-3d.png'},
-    'orgb': {'title': TEMPLATE.format('oRGB'), 'filename': 'orgb-3d.png', 'elev': 72}
+    'orgb': {'title': TEMPLATE.format('oRGB'), 'filename': 'orgb-3d.png', 'elev': 72},
+    'xyb': {'title': TEMPLATE.format('XYB'), 'filename': 'xyb-3d.png', 'azim': 45}
 }
 
 


Test patch:
diff --git a/tests/test_xyb.py b/tests/test_xyb.py
new file mode 100644
index 000000000..bb51749a1
--- /dev/null
+++ b/tests/test_xyb.py
@@ -0,0 +1,118 @@
+"""Test XYB."""
+import unittest
+from . import util
+from coloraide.everything import ColorAll as Color, NaN
+import pytest
+
+
+class TestXYB(util.ColorAssertsPyTest):
+    """Test XYB."""
+
+    COLORS = [
+        ('red', 'color(--xyb 0.0281 0.48819 0.01157)'),
+        ('orange', 'color(--xyb 0.01132 0.64596 -0.10359)'),
+        ('yellow', 'color(--xyb 0 0.81867 -0.20719)'),
+        ('green', 'color(--xyb -0.0091 0.36999 -0.17163)'),
+        ('blue', 'color(--xyb 0 0.27813 0.38801)'),
+        ('indigo', 'color(--xyb 0.00704 0.18547 0.18989)'),
+        ('violet', 'color(--xyb 0.01268 0.60656 0.15033)'),
+        ('white', 'color(--xyb 0 0.84531 0)'),
+        ('gray', 'color(--xyb 0 0.44741 0)'),
+        ('black', 'color(--xyb 0 0 0)'),
+        # Test color
+        ('color(--xyb 0.5 0.1 -0.1)', 'color(--xyb 0.5 0.1 -0.1)'),
+        ('color(--xyb 0.5 0.1 -0.1 / 0.5)', 'color(--xyb 0.5 0.1 -0.1 / 0.5)'),
+        ('color(--xyb 50% 50% -50% / 50%)', 'color(--xyb 0.225 0.4225 -0.225 / 0.5)'),
+        ('color(--xyb none none none / none)', 'color(--xyb none none none / none)'),
+        # Test percent ranges
+        ('color(--xyb 0% 0% 0%)', 'color(--xyb 0 0 0)'),
+        ('color(--xyb 100% 100% 100%)', 'color(--xyb 0.45 0.845 0.45)'),
+        ('color(--xyb -100% -100% -100%)', 'color(--xyb -0.45 -0.845 -0.45)')
+    ]
+
+    @pytest.mark.parametrize('color1,color2', COLORS)
+    def test_colors(self, color1, color2):
+        """Test colors."""
+
+        self.assertColorEqual(Color(color1).convert('xyb'), Color(color2))
+
+
+class TestXYBSerialize(util.ColorAssertsPyTest):
+    """Test XYB serialization."""
+
+    COLORS = [
+        # Test color
+        ('color(--xyb 0.1 0.75 -0.1 / 0.5)', {}, 'color(--xyb 0.1 0.75 -0.1 / 0.5)'),
+        # Test alpha
+        ('color(--xyb 0.1 0.75 -0.1)', {'alpha': True}, 'color(--xyb 0.1 0.75 -0.1 / 1)'),
+        ('color(--xyb 0.1 0.75 -0.1 / 0.5)', {'alpha': False}, 'color(--xyb 0.1 0.75 -0.1)'),
+        # Test None
+        ('color(--xyb none 0.75 -0.1)', {}, 'color(--xyb 0 0.75 -0.1)'),
+        ('color(--xyb none 0.75 -0.1)', {'none': True}, 'color(--xyb none 0.75 -0.1)'),
+        # Test Fit (not bound)
+        ('color(--xyb 1.2 0.75 -0.1)', {}, 'color(--xyb 1.2 0.75 -0.1)'),
+        ('color(--xyb 1.2 0.75 -0.1)', {'fit': False}, 'color(--xyb 1.2 0.75 -0.1)')
+    ]
+
+    @pytest.mark.parametrize('color1,options,color2', COLORS)
+    def test_colors(self, color1, options, color2):
+        """Test colors."""
+
+        self.assertEqual(Color(color1).to_string(**options), color2)
+
+
+class TestXYBPoperties(util.ColorAsserts, unittest.TestCase):
+    """Test XYB."""
+
+    def test_x(self):
+        """Test `x`."""
+
+        c = Color('color(--xyb -0.02 0.7 0.04)')
+        self.assertEqual(c['x'], -0.02)
+        c['x'] = 0.1
+        self.assertEqual(c['x'], 0.1)
+
+    def test_y(self):
+        """Test `y`."""
+
+        c = Color('color(--xyb -0.02 0.7 0.04)')
+        self.assertEqual(c['y'], 0.7)
+        c['y'] = 0.2
+        self.assertEqual(c['y'], 0.2)
+
+    def test_b(self):
+        """Test `b`."""
+
+        c = Color('color(--xyb -0.02 0.7 0.04)')
+        self.assertEqual(c['b'], 0.04)
+        c['b'] = 0.1
+        self.assertEqual(c['b'], 0.1)
+
+    def test_alpha(self):
+        """Test `alpha`."""
+
+        c = Color('color(--xyb -0.02 0.7 0.04)')
+        self.assertEqual(c['alpha'], 1)
+        c['alpha'] = 0.5
+        self.assertEqual(c['alpha'], 0.5)
+
+    def test_labish_names(self):
+        """Test `labish_names`."""
+
+        c = Color('color(--xyb -0.02 0.7 0.03 / 1)')
+        self.assertEqual(c._space.names(), ('y', 'x', 'b'))
+
+
+class TestsAchromatic(util.ColorAsserts, unittest.TestCase):
+    """Test achromatic."""
+
+    def test_achromatic(self):
+        """Test when color is achromatic."""
+
+        self.assertEqual(Color('#464646').convert('xyb').is_achromatic(), True)
+        self.assertEqual(Color('xyb', [NaN, 0, NaN]).is_achromatic(), True)
+        self.assertEqual(Color('xyb', [0.03, 0, -0.04]).is_achromatic(), False)
+        self.assertEqual(Color('xyb', [0, NaN, -0.3]).is_achromatic(), False)
+        self.assertEqual(Color('xyb', [NaN, 0.3, 0]).is_achromatic(), True)
+        self.assertEqual(Color('xyb', [NaN, NaN, 0]).is_achromatic(), True)
+        self.assertEqual(Color('xyb', [NaN, -0.5, NaN]).is_achromatic(), True)