main.js
1 /* 2 THIS IS A GENERATED/BUNDLED FILE BY ROLLUP 3 if you want to view the source visit the plugins github repository 4 */ 5 6 'use strict'; 7 8 var obsidian = require('obsidian'); 9 10 /*! ***************************************************************************** 11 Copyright (c) Microsoft Corporation. 12 13 Permission to use, copy, modify, and/or distribute this software for any 14 purpose with or without fee is hereby granted. 15 16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 17 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 19 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 20 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 22 PERFORMANCE OF THIS SOFTWARE. 23 ***************************************************************************** */ 24 25 function __awaiter(thisArg, _arguments, P, generator) { 26 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 27 return new (P || (P = Promise))(function (resolve, reject) { 28 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 29 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 30 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 31 step((generator = generator.apply(thisArg, _arguments || [])).next()); 32 }); 33 } 34 35 class ExportModal extends obsidian.Modal { 36 constructor(app, plugin, section, config) { 37 super(app); 38 this.plugin = plugin; 39 this.config = config; 40 this.section = section; 41 } 42 onOpen() { 43 const { contentEl, modalEl } = this; 44 modalEl.addClass('modal-style-settings'); 45 new obsidian.Setting(contentEl) 46 .setName(`Export settings for: ${this.section}`) 47 .then((setting) => { 48 const output = JSON.stringify(this.config, null, 2); 49 // Build a copy to clipboard link 50 setting.controlEl.createEl('a', { 51 cls: 'style-settings-copy', 52 text: 'Copy to clipboard', 53 href: '#', 54 }, (copyButton) => { 55 new obsidian.TextAreaComponent(contentEl) 56 .setValue(output) 57 .then((textarea) => { 58 copyButton.addEventListener('click', (e) => { 59 e.preventDefault(); 60 // Select the textarea contents and copy them to the clipboard 61 textarea.inputEl.select(); 62 textarea.inputEl.setSelectionRange(0, 99999); 63 document.execCommand('copy'); 64 copyButton.addClass('success'); 65 setTimeout(() => { 66 // If the button is still in the dom, remove the success class 67 if (copyButton.parentNode) { 68 copyButton.removeClass('success'); 69 } 70 }, 2000); 71 }); 72 }); 73 }); 74 // Build a download link 75 setting.controlEl.createEl('a', { 76 cls: 'style-settings-download', 77 text: 'Download', 78 attr: { 79 download: 'style-settings.json', 80 href: `data:application/json;charset=utf-8,${encodeURIComponent(output)}`, 81 }, 82 }); 83 }); 84 } 85 onClose() { 86 const { contentEl } = this; 87 contentEl.empty(); 88 } 89 } 90 91 class ImportModal extends obsidian.Modal { 92 constructor(app, plugin) { 93 super(app); 94 this.plugin = plugin; 95 } 96 onOpen() { 97 const { contentEl, modalEl } = this; 98 modalEl.addClass('modal-style-settings'); 99 new obsidian.Setting(contentEl) 100 .setName('Import style setting') 101 .setDesc('Import an entire or partial configuration. Warning: this may override existing settings'); 102 new obsidian.Setting(contentEl).then((setting) => { 103 // Build an error message container 104 const errorSpan = createSpan({ 105 cls: 'style-settings-import-error', 106 text: 'Error importing config', 107 }); 108 setting.nameEl.appendChild(errorSpan); 109 // Attempt to parse the imported data and close if successful 110 const importAndClose = (str) => __awaiter(this, void 0, void 0, function* () { 111 if (str) { 112 try { 113 const importedSettings = JSON.parse(str); 114 yield this.plugin.settingsManager.setSettings(importedSettings); 115 this.plugin.settingsTab.display(); 116 this.close(); 117 } 118 catch (e) { 119 errorSpan.addClass('active'); 120 errorSpan.setText(`Error importing style settings: ${e}`); 121 } 122 } 123 else { 124 errorSpan.addClass('active'); 125 errorSpan.setText(`Error importing style settings: config is empty`); 126 } 127 }); 128 // Build a file input 129 setting.controlEl.createEl('input', { 130 cls: 'style-settings-import-input', 131 attr: { 132 id: 'style-settings-import-input', 133 name: 'style-settings-import-input', 134 type: 'file', 135 accept: '.json', 136 }, 137 }, (importInput) => { 138 // Set up a FileReader so we can parse the file contents 139 importInput.addEventListener('change', (e) => { 140 const reader = new FileReader(); 141 reader.onload = (e) => __awaiter(this, void 0, void 0, function* () { 142 yield importAndClose(e.target.result.toString().trim()); 143 }); 144 reader.readAsText(e.target.files[0]); 145 }); 146 }); 147 // Build a label we will style as a link 148 setting.controlEl.createEl('label', { 149 cls: 'style-settings-import-label', 150 text: 'Import from file', 151 attr: { 152 for: 'style-settings-import-input', 153 }, 154 }); 155 new obsidian.TextAreaComponent(contentEl) 156 .setPlaceholder('Paste config here...') 157 .then((ta) => { 158 new obsidian.ButtonComponent(contentEl) 159 .setButtonText('Save') 160 .onClick(() => __awaiter(this, void 0, void 0, function* () { 161 yield importAndClose(ta.getValue().trim()); 162 })); 163 }); 164 }); 165 } 166 onClose() { 167 const { contentEl } = this; 168 contentEl.empty(); 169 } 170 } 171 172 const SettingType = { 173 HEADING: 'heading', 174 INFO_TEXT: 'info-text', 175 CLASS_TOGGLE: 'class-toggle', 176 CLASS_SELECT: 'class-select', 177 VARIABLE_TEXT: 'variable-text', 178 VARIABLE_NUMBER: 'variable-number', 179 VARIABLE_NUMBER_SLIDER: 'variable-number-slider', 180 VARIABLE_SELECT: 'variable-select', 181 VARIABLE_COLOR: 'variable-color', 182 VARIABLE_THEMED_COLOR: 'variable-themed-color', 183 COLOR_GRADIENT: 'color-gradient', 184 }; 185 186 var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; 187 188 function getDefaultExportFromCjs (x) { 189 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; 190 } 191 192 function createCommonjsModule(fn, basedir, module) { 193 return module = { 194 path: basedir, 195 exports: {}, 196 require: function (path, base) { 197 return commonjsRequire(path, (base === undefined || base === null) ? module.path : base); 198 } 199 }, fn(module, module.exports), module.exports; 200 } 201 202 function commonjsRequire () { 203 throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs'); 204 } 205 206 var chroma = createCommonjsModule(function (module, exports) { 207 /** 208 * chroma.js - JavaScript library for color conversions 209 * 210 * Copyright (c) 2011-2019, Gregor Aisch 211 * All rights reserved. 212 * 213 * Redistribution and use in source and binary forms, with or without 214 * modification, are permitted provided that the following conditions are met: 215 * 216 * 1. Redistributions of source code must retain the above copyright notice, this 217 * list of conditions and the following disclaimer. 218 * 219 * 2. Redistributions in binary form must reproduce the above copyright notice, 220 * this list of conditions and the following disclaimer in the documentation 221 * and/or other materials provided with the distribution. 222 * 223 * 3. The name Gregor Aisch may not be used to endorse or promote products 224 * derived from this software without specific prior written permission. 225 * 226 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 227 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 228 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 229 * DISCLAIMED. IN NO EVENT SHALL GREGOR AISCH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 230 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 231 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 233 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 234 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 235 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 236 * 237 * ------------------------------------------------------- 238 * 239 * chroma.js includes colors from colorbrewer2.org, which are released under 240 * the following license: 241 * 242 * Copyright (c) 2002 Cynthia Brewer, Mark Harrower, 243 * and The Pennsylvania State University. 244 * 245 * Licensed under the Apache License, Version 2.0 (the "License"); 246 * you may not use this file except in compliance with the License. 247 * You may obtain a copy of the License at 248 * http://www.apache.org/licenses/LICENSE-2.0 249 * 250 * Unless required by applicable law or agreed to in writing, 251 * software distributed under the License is distributed on an 252 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 253 * either express or implied. See the License for the specific 254 * language governing permissions and limitations under the License. 255 * 256 * ------------------------------------------------------ 257 * 258 * Named colors are taken from X11 Color Names. 259 * http://www.w3.org/TR/css3-color/#svg-color 260 * 261 * @preserve 262 */ 263 264 (function (global, factory) { 265 module.exports = factory() ; 266 }(commonjsGlobal, (function () { 267 var limit = function (x, min, max) { 268 if ( min === void 0 ) min=0; 269 if ( max === void 0 ) max=1; 270 271 return x < min ? min : x > max ? max : x; 272 }; 273 274 var clip_rgb = function (rgb) { 275 rgb._clipped = false; 276 rgb._unclipped = rgb.slice(0); 277 for (var i=0; i<=3; i++) { 278 if (i < 3) { 279 if (rgb[i] < 0 || rgb[i] > 255) { rgb._clipped = true; } 280 rgb[i] = limit(rgb[i], 0, 255); 281 } else if (i === 3) { 282 rgb[i] = limit(rgb[i], 0, 1); 283 } 284 } 285 return rgb; 286 }; 287 288 // ported from jQuery's $.type 289 var classToType = {}; 290 for (var i = 0, list = ['Boolean', 'Number', 'String', 'Function', 'Array', 'Date', 'RegExp', 'Undefined', 'Null']; i < list.length; i += 1) { 291 var name = list[i]; 292 293 classToType[("[object " + name + "]")] = name.toLowerCase(); 294 } 295 var type = function(obj) { 296 return classToType[Object.prototype.toString.call(obj)] || "object"; 297 }; 298 299 var unpack = function (args, keyOrder) { 300 if ( keyOrder === void 0 ) keyOrder=null; 301 302 // if called with more than 3 arguments, we return the arguments 303 if (args.length >= 3) { return Array.prototype.slice.call(args); } 304 // with less than 3 args we check if first arg is object 305 // and use the keyOrder string to extract and sort properties 306 if (type(args[0]) == 'object' && keyOrder) { 307 return keyOrder.split('') 308 .filter(function (k) { return args[0][k] !== undefined; }) 309 .map(function (k) { return args[0][k]; }); 310 } 311 // otherwise we just return the first argument 312 // (which we suppose is an array of args) 313 return args[0]; 314 }; 315 316 var last = function (args) { 317 if (args.length < 2) { return null; } 318 var l = args.length-1; 319 if (type(args[l]) == 'string') { return args[l].toLowerCase(); } 320 return null; 321 }; 322 323 var PI = Math.PI; 324 325 var utils = { 326 clip_rgb: clip_rgb, 327 limit: limit, 328 type: type, 329 unpack: unpack, 330 last: last, 331 PI: PI, 332 TWOPI: PI*2, 333 PITHIRD: PI/3, 334 DEG2RAD: PI / 180, 335 RAD2DEG: 180 / PI 336 }; 337 338 var input = { 339 format: {}, 340 autodetect: [] 341 }; 342 343 var last$1 = utils.last; 344 var clip_rgb$1 = utils.clip_rgb; 345 var type$1 = utils.type; 346 347 348 var Color = function Color() { 349 var args = [], len = arguments.length; 350 while ( len-- ) args[ len ] = arguments[ len ]; 351 352 var me = this; 353 if (type$1(args[0]) === 'object' && 354 args[0].constructor && 355 args[0].constructor === this.constructor) { 356 // the argument is already a Color instance 357 return args[0]; 358 } 359 360 // last argument could be the mode 361 var mode = last$1(args); 362 var autodetect = false; 363 364 if (!mode) { 365 autodetect = true; 366 if (!input.sorted) { 367 input.autodetect = input.autodetect.sort(function (a,b) { return b.p - a.p; }); 368 input.sorted = true; 369 } 370 // auto-detect format 371 for (var i = 0, list = input.autodetect; i < list.length; i += 1) { 372 var chk = list[i]; 373 374 mode = chk.test.apply(chk, args); 375 if (mode) { break; } 376 } 377 } 378 379 if (input.format[mode]) { 380 var rgb = input.format[mode].apply(null, autodetect ? args : args.slice(0,-1)); 381 me._rgb = clip_rgb$1(rgb); 382 } else { 383 throw new Error('unknown format: '+args); 384 } 385 386 // add alpha channel 387 if (me._rgb.length === 3) { me._rgb.push(1); } 388 }; 389 390 Color.prototype.toString = function toString () { 391 if (type$1(this.hex) == 'function') { return this.hex(); } 392 return ("[" + (this._rgb.join(',')) + "]"); 393 }; 394 395 var Color_1 = Color; 396 397 var chroma = function () { 398 var args = [], len = arguments.length; 399 while ( len-- ) args[ len ] = arguments[ len ]; 400 401 return new (Function.prototype.bind.apply( chroma.Color, [ null ].concat( args) )); 402 }; 403 404 chroma.Color = Color_1; 405 chroma.version = '2.1.2'; 406 407 var chroma_1 = chroma; 408 409 var unpack$1 = utils.unpack; 410 var max = Math.max; 411 412 var rgb2cmyk = function () { 413 var args = [], len = arguments.length; 414 while ( len-- ) args[ len ] = arguments[ len ]; 415 416 var ref = unpack$1(args, 'rgb'); 417 var r = ref[0]; 418 var g = ref[1]; 419 var b = ref[2]; 420 r = r / 255; 421 g = g / 255; 422 b = b / 255; 423 var k = 1 - max(r,max(g,b)); 424 var f = k < 1 ? 1 / (1-k) : 0; 425 var c = (1-r-k) * f; 426 var m = (1-g-k) * f; 427 var y = (1-b-k) * f; 428 return [c,m,y,k]; 429 }; 430 431 var rgb2cmyk_1 = rgb2cmyk; 432 433 var unpack$2 = utils.unpack; 434 435 var cmyk2rgb = function () { 436 var args = [], len = arguments.length; 437 while ( len-- ) args[ len ] = arguments[ len ]; 438 439 args = unpack$2(args, 'cmyk'); 440 var c = args[0]; 441 var m = args[1]; 442 var y = args[2]; 443 var k = args[3]; 444 var alpha = args.length > 4 ? args[4] : 1; 445 if (k === 1) { return [0,0,0,alpha]; } 446 return [ 447 c >= 1 ? 0 : 255 * (1-c) * (1-k), // r 448 m >= 1 ? 0 : 255 * (1-m) * (1-k), // g 449 y >= 1 ? 0 : 255 * (1-y) * (1-k), // b 450 alpha 451 ]; 452 }; 453 454 var cmyk2rgb_1 = cmyk2rgb; 455 456 var unpack$3 = utils.unpack; 457 var type$2 = utils.type; 458 459 460 461 Color_1.prototype.cmyk = function() { 462 return rgb2cmyk_1(this._rgb); 463 }; 464 465 chroma_1.cmyk = function () { 466 var args = [], len = arguments.length; 467 while ( len-- ) args[ len ] = arguments[ len ]; 468 469 return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['cmyk']) )); 470 }; 471 472 input.format.cmyk = cmyk2rgb_1; 473 474 input.autodetect.push({ 475 p: 2, 476 test: function () { 477 var args = [], len = arguments.length; 478 while ( len-- ) args[ len ] = arguments[ len ]; 479 480 args = unpack$3(args, 'cmyk'); 481 if (type$2(args) === 'array' && args.length === 4) { 482 return 'cmyk'; 483 } 484 } 485 }); 486 487 var unpack$4 = utils.unpack; 488 var last$2 = utils.last; 489 var rnd = function (a) { return Math.round(a*100)/100; }; 490 491 /* 492 * supported arguments: 493 * - hsl2css(h,s,l) 494 * - hsl2css(h,s,l,a) 495 * - hsl2css([h,s,l], mode) 496 * - hsl2css([h,s,l,a], mode) 497 * - hsl2css({h,s,l,a}, mode) 498 */ 499 var hsl2css = function () { 500 var args = [], len = arguments.length; 501 while ( len-- ) args[ len ] = arguments[ len ]; 502 503 var hsla = unpack$4(args, 'hsla'); 504 var mode = last$2(args) || 'lsa'; 505 hsla[0] = rnd(hsla[0] || 0); 506 hsla[1] = rnd(hsla[1]*100) + '%'; 507 hsla[2] = rnd(hsla[2]*100) + '%'; 508 if (mode === 'hsla' || (hsla.length > 3 && hsla[3]<1)) { 509 hsla[3] = hsla.length > 3 ? hsla[3] : 1; 510 mode = 'hsla'; 511 } else { 512 hsla.length = 3; 513 } 514 return (mode + "(" + (hsla.join(',')) + ")"); 515 }; 516 517 var hsl2css_1 = hsl2css; 518 519 var unpack$5 = utils.unpack; 520 521 /* 522 * supported arguments: 523 * - rgb2hsl(r,g,b) 524 * - rgb2hsl(r,g,b,a) 525 * - rgb2hsl([r,g,b]) 526 * - rgb2hsl([r,g,b,a]) 527 * - rgb2hsl({r,g,b,a}) 528 */ 529 var rgb2hsl = function () { 530 var args = [], len = arguments.length; 531 while ( len-- ) args[ len ] = arguments[ len ]; 532 533 args = unpack$5(args, 'rgba'); 534 var r = args[0]; 535 var g = args[1]; 536 var b = args[2]; 537 538 r /= 255; 539 g /= 255; 540 b /= 255; 541 542 var min = Math.min(r, g, b); 543 var max = Math.max(r, g, b); 544 545 var l = (max + min) / 2; 546 var s, h; 547 548 if (max === min){ 549 s = 0; 550 h = Number.NaN; 551 } else { 552 s = l < 0.5 ? (max - min) / (max + min) : (max - min) / (2 - max - min); 553 } 554 555 if (r == max) { h = (g - b) / (max - min); } 556 else if (g == max) { h = 2 + (b - r) / (max - min); } 557 else if (b == max) { h = 4 + (r - g) / (max - min); } 558 559 h *= 60; 560 if (h < 0) { h += 360; } 561 if (args.length>3 && args[3]!==undefined) { return [h,s,l,args[3]]; } 562 return [h,s,l]; 563 }; 564 565 var rgb2hsl_1 = rgb2hsl; 566 567 var unpack$6 = utils.unpack; 568 var last$3 = utils.last; 569 570 571 var round = Math.round; 572 573 /* 574 * supported arguments: 575 * - rgb2css(r,g,b) 576 * - rgb2css(r,g,b,a) 577 * - rgb2css([r,g,b], mode) 578 * - rgb2css([r,g,b,a], mode) 579 * - rgb2css({r,g,b,a}, mode) 580 */ 581 var rgb2css = function () { 582 var args = [], len = arguments.length; 583 while ( len-- ) args[ len ] = arguments[ len ]; 584 585 var rgba = unpack$6(args, 'rgba'); 586 var mode = last$3(args) || 'rgb'; 587 if (mode.substr(0,3) == 'hsl') { 588 return hsl2css_1(rgb2hsl_1(rgba), mode); 589 } 590 rgba[0] = round(rgba[0]); 591 rgba[1] = round(rgba[1]); 592 rgba[2] = round(rgba[2]); 593 if (mode === 'rgba' || (rgba.length > 3 && rgba[3]<1)) { 594 rgba[3] = rgba.length > 3 ? rgba[3] : 1; 595 mode = 'rgba'; 596 } 597 return (mode + "(" + (rgba.slice(0,mode==='rgb'?3:4).join(',')) + ")"); 598 }; 599 600 var rgb2css_1 = rgb2css; 601 602 var unpack$7 = utils.unpack; 603 var round$1 = Math.round; 604 605 var hsl2rgb = function () { 606 var assign; 607 608 var args = [], len = arguments.length; 609 while ( len-- ) args[ len ] = arguments[ len ]; 610 args = unpack$7(args, 'hsl'); 611 var h = args[0]; 612 var s = args[1]; 613 var l = args[2]; 614 var r,g,b; 615 if (s === 0) { 616 r = g = b = l*255; 617 } else { 618 var t3 = [0,0,0]; 619 var c = [0,0,0]; 620 var t2 = l < 0.5 ? l * (1+s) : l+s-l*s; 621 var t1 = 2 * l - t2; 622 var h_ = h / 360; 623 t3[0] = h_ + 1/3; 624 t3[1] = h_; 625 t3[2] = h_ - 1/3; 626 for (var i=0; i<3; i++) { 627 if (t3[i] < 0) { t3[i] += 1; } 628 if (t3[i] > 1) { t3[i] -= 1; } 629 if (6 * t3[i] < 1) 630 { c[i] = t1 + (t2 - t1) * 6 * t3[i]; } 631 else if (2 * t3[i] < 1) 632 { c[i] = t2; } 633 else if (3 * t3[i] < 2) 634 { c[i] = t1 + (t2 - t1) * ((2 / 3) - t3[i]) * 6; } 635 else 636 { c[i] = t1; } 637 } 638 (assign = [round$1(c[0]*255),round$1(c[1]*255),round$1(c[2]*255)], r = assign[0], g = assign[1], b = assign[2]); 639 } 640 if (args.length > 3) { 641 // keep alpha channel 642 return [r,g,b,args[3]]; 643 } 644 return [r,g,b,1]; 645 }; 646 647 var hsl2rgb_1 = hsl2rgb; 648 649 var RE_RGB = /^rgb\(\s*(-?\d+),\s*(-?\d+)\s*,\s*(-?\d+)\s*\)$/; 650 var RE_RGBA = /^rgba\(\s*(-?\d+),\s*(-?\d+)\s*,\s*(-?\d+)\s*,\s*([01]|[01]?\.\d+)\)$/; 651 var RE_RGB_PCT = /^rgb\(\s*(-?\d+(?:\.\d+)?)%,\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*\)$/; 652 var RE_RGBA_PCT = /^rgba\(\s*(-?\d+(?:\.\d+)?)%,\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/; 653 var RE_HSL = /^hsl\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*\)$/; 654 var RE_HSLA = /^hsla\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/; 655 656 var round$2 = Math.round; 657 658 var css2rgb = function (css) { 659 css = css.toLowerCase().trim(); 660 var m; 661 662 if (input.format.named) { 663 try { 664 return input.format.named(css); 665 } catch (e) { 666 // eslint-disable-next-line 667 } 668 } 669 670 // rgb(250,20,0) 671 if ((m = css.match(RE_RGB))) { 672 var rgb = m.slice(1,4); 673 for (var i=0; i<3; i++) { 674 rgb[i] = +rgb[i]; 675 } 676 rgb[3] = 1; // default alpha 677 return rgb; 678 } 679 680 // rgba(250,20,0,0.4) 681 if ((m = css.match(RE_RGBA))) { 682 var rgb$1 = m.slice(1,5); 683 for (var i$1=0; i$1<4; i$1++) { 684 rgb$1[i$1] = +rgb$1[i$1]; 685 } 686 return rgb$1; 687 } 688 689 // rgb(100%,0%,0%) 690 if ((m = css.match(RE_RGB_PCT))) { 691 var rgb$2 = m.slice(1,4); 692 for (var i$2=0; i$2<3; i$2++) { 693 rgb$2[i$2] = round$2(rgb$2[i$2] * 2.55); 694 } 695 rgb$2[3] = 1; // default alpha 696 return rgb$2; 697 } 698 699 // rgba(100%,0%,0%,0.4) 700 if ((m = css.match(RE_RGBA_PCT))) { 701 var rgb$3 = m.slice(1,5); 702 for (var i$3=0; i$3<3; i$3++) { 703 rgb$3[i$3] = round$2(rgb$3[i$3] * 2.55); 704 } 705 rgb$3[3] = +rgb$3[3]; 706 return rgb$3; 707 } 708 709 // hsl(0,100%,50%) 710 if ((m = css.match(RE_HSL))) { 711 var hsl = m.slice(1,4); 712 hsl[1] *= 0.01; 713 hsl[2] *= 0.01; 714 var rgb$4 = hsl2rgb_1(hsl); 715 rgb$4[3] = 1; 716 return rgb$4; 717 } 718 719 // hsla(0,100%,50%,0.5) 720 if ((m = css.match(RE_HSLA))) { 721 var hsl$1 = m.slice(1,4); 722 hsl$1[1] *= 0.01; 723 hsl$1[2] *= 0.01; 724 var rgb$5 = hsl2rgb_1(hsl$1); 725 rgb$5[3] = +m[4]; // default alpha = 1 726 return rgb$5; 727 } 728 }; 729 730 css2rgb.test = function (s) { 731 return RE_RGB.test(s) || 732 RE_RGBA.test(s) || 733 RE_RGB_PCT.test(s) || 734 RE_RGBA_PCT.test(s) || 735 RE_HSL.test(s) || 736 RE_HSLA.test(s); 737 }; 738 739 var css2rgb_1 = css2rgb; 740 741 var type$3 = utils.type; 742 743 744 745 746 Color_1.prototype.css = function(mode) { 747 return rgb2css_1(this._rgb, mode); 748 }; 749 750 chroma_1.css = function () { 751 var args = [], len = arguments.length; 752 while ( len-- ) args[ len ] = arguments[ len ]; 753 754 return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['css']) )); 755 }; 756 757 input.format.css = css2rgb_1; 758 759 input.autodetect.push({ 760 p: 5, 761 test: function (h) { 762 var rest = [], len = arguments.length - 1; 763 while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ]; 764 765 if (!rest.length && type$3(h) === 'string' && css2rgb_1.test(h)) { 766 return 'css'; 767 } 768 } 769 }); 770 771 var unpack$8 = utils.unpack; 772 773 input.format.gl = function () { 774 var args = [], len = arguments.length; 775 while ( len-- ) args[ len ] = arguments[ len ]; 776 777 var rgb = unpack$8(args, 'rgba'); 778 rgb[0] *= 255; 779 rgb[1] *= 255; 780 rgb[2] *= 255; 781 return rgb; 782 }; 783 784 chroma_1.gl = function () { 785 var args = [], len = arguments.length; 786 while ( len-- ) args[ len ] = arguments[ len ]; 787 788 return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['gl']) )); 789 }; 790 791 Color_1.prototype.gl = function() { 792 var rgb = this._rgb; 793 return [rgb[0]/255, rgb[1]/255, rgb[2]/255, rgb[3]]; 794 }; 795 796 var unpack$9 = utils.unpack; 797 798 var rgb2hcg = function () { 799 var args = [], len = arguments.length; 800 while ( len-- ) args[ len ] = arguments[ len ]; 801 802 var ref = unpack$9(args, 'rgb'); 803 var r = ref[0]; 804 var g = ref[1]; 805 var b = ref[2]; 806 var min = Math.min(r, g, b); 807 var max = Math.max(r, g, b); 808 var delta = max - min; 809 var c = delta * 100 / 255; 810 var _g = min / (255 - delta) * 100; 811 var h; 812 if (delta === 0) { 813 h = Number.NaN; 814 } else { 815 if (r === max) { h = (g - b) / delta; } 816 if (g === max) { h = 2+(b - r) / delta; } 817 if (b === max) { h = 4+(r - g) / delta; } 818 h *= 60; 819 if (h < 0) { h += 360; } 820 } 821 return [h, c, _g]; 822 }; 823 824 var rgb2hcg_1 = rgb2hcg; 825 826 var unpack$a = utils.unpack; 827 var floor = Math.floor; 828 829 /* 830 * this is basically just HSV with some minor tweaks 831 * 832 * hue.. [0..360] 833 * chroma .. [0..1] 834 * grayness .. [0..1] 835 */ 836 837 var hcg2rgb = function () { 838 var assign, assign$1, assign$2, assign$3, assign$4, assign$5; 839 840 var args = [], len = arguments.length; 841 while ( len-- ) args[ len ] = arguments[ len ]; 842 args = unpack$a(args, 'hcg'); 843 var h = args[0]; 844 var c = args[1]; 845 var _g = args[2]; 846 var r,g,b; 847 _g = _g * 255; 848 var _c = c * 255; 849 if (c === 0) { 850 r = g = b = _g; 851 } else { 852 if (h === 360) { h = 0; } 853 if (h > 360) { h -= 360; } 854 if (h < 0) { h += 360; } 855 h /= 60; 856 var i = floor(h); 857 var f = h - i; 858 var p = _g * (1 - c); 859 var q = p + _c * (1 - f); 860 var t = p + _c * f; 861 var v = p + _c; 862 switch (i) { 863 case 0: (assign = [v, t, p], r = assign[0], g = assign[1], b = assign[2]); break 864 case 1: (assign$1 = [q, v, p], r = assign$1[0], g = assign$1[1], b = assign$1[2]); break 865 case 2: (assign$2 = [p, v, t], r = assign$2[0], g = assign$2[1], b = assign$2[2]); break 866 case 3: (assign$3 = [p, q, v], r = assign$3[0], g = assign$3[1], b = assign$3[2]); break 867 case 4: (assign$4 = [t, p, v], r = assign$4[0], g = assign$4[1], b = assign$4[2]); break 868 case 5: (assign$5 = [v, p, q], r = assign$5[0], g = assign$5[1], b = assign$5[2]); break 869 } 870 } 871 return [r, g, b, args.length > 3 ? args[3] : 1]; 872 }; 873 874 var hcg2rgb_1 = hcg2rgb; 875 876 var unpack$b = utils.unpack; 877 var type$4 = utils.type; 878 879 880 881 882 883 884 Color_1.prototype.hcg = function() { 885 return rgb2hcg_1(this._rgb); 886 }; 887 888 chroma_1.hcg = function () { 889 var args = [], len = arguments.length; 890 while ( len-- ) args[ len ] = arguments[ len ]; 891 892 return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['hcg']) )); 893 }; 894 895 input.format.hcg = hcg2rgb_1; 896 897 input.autodetect.push({ 898 p: 1, 899 test: function () { 900 var args = [], len = arguments.length; 901 while ( len-- ) args[ len ] = arguments[ len ]; 902 903 args = unpack$b(args, 'hcg'); 904 if (type$4(args) === 'array' && args.length === 3) { 905 return 'hcg'; 906 } 907 } 908 }); 909 910 var unpack$c = utils.unpack; 911 var last$4 = utils.last; 912 var round$3 = Math.round; 913 914 var rgb2hex = function () { 915 var args = [], len = arguments.length; 916 while ( len-- ) args[ len ] = arguments[ len ]; 917 918 var ref = unpack$c(args, 'rgba'); 919 var r = ref[0]; 920 var g = ref[1]; 921 var b = ref[2]; 922 var a = ref[3]; 923 var mode = last$4(args) || 'auto'; 924 if (a === undefined) { a = 1; } 925 if (mode === 'auto') { 926 mode = a < 1 ? 'rgba' : 'rgb'; 927 } 928 r = round$3(r); 929 g = round$3(g); 930 b = round$3(b); 931 var u = r << 16 | g << 8 | b; 932 var str = "000000" + u.toString(16); //#.toUpperCase(); 933 str = str.substr(str.length - 6); 934 var hxa = '0' + round$3(a * 255).toString(16); 935 hxa = hxa.substr(hxa.length - 2); 936 switch (mode.toLowerCase()) { 937 case 'rgba': return ("#" + str + hxa); 938 case 'argb': return ("#" + hxa + str); 939 default: return ("#" + str); 940 } 941 }; 942 943 var rgb2hex_1 = rgb2hex; 944 945 var RE_HEX = /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; 946 var RE_HEXA = /^#?([A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/; 947 948 var hex2rgb = function (hex) { 949 if (hex.match(RE_HEX)) { 950 // remove optional leading # 951 if (hex.length === 4 || hex.length === 7) { 952 hex = hex.substr(1); 953 } 954 // expand short-notation to full six-digit 955 if (hex.length === 3) { 956 hex = hex.split(''); 957 hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2]; 958 } 959 var u = parseInt(hex, 16); 960 var r = u >> 16; 961 var g = u >> 8 & 0xFF; 962 var b = u & 0xFF; 963 return [r,g,b,1]; 964 } 965 966 // match rgba hex format, eg #FF000077 967 if (hex.match(RE_HEXA)) { 968 if (hex.length === 5 || hex.length === 9) { 969 // remove optional leading # 970 hex = hex.substr(1); 971 } 972 // expand short-notation to full eight-digit 973 if (hex.length === 4) { 974 hex = hex.split(''); 975 hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2]+hex[3]+hex[3]; 976 } 977 var u$1 = parseInt(hex, 16); 978 var r$1 = u$1 >> 24 & 0xFF; 979 var g$1 = u$1 >> 16 & 0xFF; 980 var b$1 = u$1 >> 8 & 0xFF; 981 var a = Math.round((u$1 & 0xFF) / 0xFF * 100) / 100; 982 return [r$1,g$1,b$1,a]; 983 } 984 985 // we used to check for css colors here 986 // if _input.css? and rgb = _input.css hex 987 // return rgb 988 989 throw new Error(("unknown hex color: " + hex)); 990 }; 991 992 var hex2rgb_1 = hex2rgb; 993 994 var type$5 = utils.type; 995 996 997 998 999 Color_1.prototype.hex = function(mode) { 1000 return rgb2hex_1(this._rgb, mode); 1001 }; 1002 1003 chroma_1.hex = function () { 1004 var args = [], len = arguments.length; 1005 while ( len-- ) args[ len ] = arguments[ len ]; 1006 1007 return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['hex']) )); 1008 }; 1009 1010 input.format.hex = hex2rgb_1; 1011 input.autodetect.push({ 1012 p: 4, 1013 test: function (h) { 1014 var rest = [], len = arguments.length - 1; 1015 while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ]; 1016 1017 if (!rest.length && type$5(h) === 'string' && [3,4,5,6,7,8,9].indexOf(h.length) >= 0) { 1018 return 'hex'; 1019 } 1020 } 1021 }); 1022 1023 var unpack$d = utils.unpack; 1024 var TWOPI = utils.TWOPI; 1025 var min = Math.min; 1026 var sqrt = Math.sqrt; 1027 var acos = Math.acos; 1028 1029 var rgb2hsi = function () { 1030 var args = [], len = arguments.length; 1031 while ( len-- ) args[ len ] = arguments[ len ]; 1032 1033 /* 1034 borrowed from here: 1035 http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/rgb2hsi.cpp 1036 */ 1037 var ref = unpack$d(args, 'rgb'); 1038 var r = ref[0]; 1039 var g = ref[1]; 1040 var b = ref[2]; 1041 r /= 255; 1042 g /= 255; 1043 b /= 255; 1044 var h; 1045 var min_ = min(r,g,b); 1046 var i = (r+g+b) / 3; 1047 var s = i > 0 ? 1 - min_/i : 0; 1048 if (s === 0) { 1049 h = NaN; 1050 } else { 1051 h = ((r-g)+(r-b)) / 2; 1052 h /= sqrt((r-g)*(r-g) + (r-b)*(g-b)); 1053 h = acos(h); 1054 if (b > g) { 1055 h = TWOPI - h; 1056 } 1057 h /= TWOPI; 1058 } 1059 return [h*360,s,i]; 1060 }; 1061 1062 var rgb2hsi_1 = rgb2hsi; 1063 1064 var unpack$e = utils.unpack; 1065 var limit$1 = utils.limit; 1066 var TWOPI$1 = utils.TWOPI; 1067 var PITHIRD = utils.PITHIRD; 1068 var cos = Math.cos; 1069 1070 /* 1071 * hue [0..360] 1072 * saturation [0..1] 1073 * intensity [0..1] 1074 */ 1075 var hsi2rgb = function () { 1076 var args = [], len = arguments.length; 1077 while ( len-- ) args[ len ] = arguments[ len ]; 1078 1079 /* 1080 borrowed from here: 1081 http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/hsi2rgb.cpp 1082 */ 1083 args = unpack$e(args, 'hsi'); 1084 var h = args[0]; 1085 var s = args[1]; 1086 var i = args[2]; 1087 var r,g,b; 1088 1089 if (isNaN(h)) { h = 0; } 1090 if (isNaN(s)) { s = 0; } 1091 // normalize hue 1092 if (h > 360) { h -= 360; } 1093 if (h < 0) { h += 360; } 1094 h /= 360; 1095 if (h < 1/3) { 1096 b = (1-s)/3; 1097 r = (1+s*cos(TWOPI$1*h)/cos(PITHIRD-TWOPI$1*h))/3; 1098 g = 1 - (b+r); 1099 } else if (h < 2/3) { 1100 h -= 1/3; 1101 r = (1-s)/3; 1102 g = (1+s*cos(TWOPI$1*h)/cos(PITHIRD-TWOPI$1*h))/3; 1103 b = 1 - (r+g); 1104 } else { 1105 h -= 2/3; 1106 g = (1-s)/3; 1107 b = (1+s*cos(TWOPI$1*h)/cos(PITHIRD-TWOPI$1*h))/3; 1108 r = 1 - (g+b); 1109 } 1110 r = limit$1(i*r*3); 1111 g = limit$1(i*g*3); 1112 b = limit$1(i*b*3); 1113 return [r*255, g*255, b*255, args.length > 3 ? args[3] : 1]; 1114 }; 1115 1116 var hsi2rgb_1 = hsi2rgb; 1117 1118 var unpack$f = utils.unpack; 1119 var type$6 = utils.type; 1120 1121 1122 1123 1124 1125 1126 Color_1.prototype.hsi = function() { 1127 return rgb2hsi_1(this._rgb); 1128 }; 1129 1130 chroma_1.hsi = function () { 1131 var args = [], len = arguments.length; 1132 while ( len-- ) args[ len ] = arguments[ len ]; 1133 1134 return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['hsi']) )); 1135 }; 1136 1137 input.format.hsi = hsi2rgb_1; 1138 1139 input.autodetect.push({ 1140 p: 2, 1141 test: function () { 1142 var args = [], len = arguments.length; 1143 while ( len-- ) args[ len ] = arguments[ len ]; 1144 1145 args = unpack$f(args, 'hsi'); 1146 if (type$6(args) === 'array' && args.length === 3) { 1147 return 'hsi'; 1148 } 1149 } 1150 }); 1151 1152 var unpack$g = utils.unpack; 1153 var type$7 = utils.type; 1154 1155 1156 1157 1158 1159 1160 Color_1.prototype.hsl = function() { 1161 return rgb2hsl_1(this._rgb); 1162 }; 1163 1164 chroma_1.hsl = function () { 1165 var args = [], len = arguments.length; 1166 while ( len-- ) args[ len ] = arguments[ len ]; 1167 1168 return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['hsl']) )); 1169 }; 1170 1171 input.format.hsl = hsl2rgb_1; 1172 1173 input.autodetect.push({ 1174 p: 2, 1175 test: function () { 1176 var args = [], len = arguments.length; 1177 while ( len-- ) args[ len ] = arguments[ len ]; 1178 1179 args = unpack$g(args, 'hsl'); 1180 if (type$7(args) === 'array' && args.length === 3) { 1181 return 'hsl'; 1182 } 1183 } 1184 }); 1185 1186 var unpack$h = utils.unpack; 1187 var min$1 = Math.min; 1188 var max$1 = Math.max; 1189 1190 /* 1191 * supported arguments: 1192 * - rgb2hsv(r,g,b) 1193 * - rgb2hsv([r,g,b]) 1194 * - rgb2hsv({r,g,b}) 1195 */ 1196 var rgb2hsl$1 = function () { 1197 var args = [], len = arguments.length; 1198 while ( len-- ) args[ len ] = arguments[ len ]; 1199 1200 args = unpack$h(args, 'rgb'); 1201 var r = args[0]; 1202 var g = args[1]; 1203 var b = args[2]; 1204 var min_ = min$1(r, g, b); 1205 var max_ = max$1(r, g, b); 1206 var delta = max_ - min_; 1207 var h,s,v; 1208 v = max_ / 255.0; 1209 if (max_ === 0) { 1210 h = Number.NaN; 1211 s = 0; 1212 } else { 1213 s = delta / max_; 1214 if (r === max_) { h = (g - b) / delta; } 1215 if (g === max_) { h = 2+(b - r) / delta; } 1216 if (b === max_) { h = 4+(r - g) / delta; } 1217 h *= 60; 1218 if (h < 0) { h += 360; } 1219 } 1220 return [h, s, v] 1221 }; 1222 1223 var rgb2hsv = rgb2hsl$1; 1224 1225 var unpack$i = utils.unpack; 1226 var floor$1 = Math.floor; 1227 1228 var hsv2rgb = function () { 1229 var assign, assign$1, assign$2, assign$3, assign$4, assign$5; 1230 1231 var args = [], len = arguments.length; 1232 while ( len-- ) args[ len ] = arguments[ len ]; 1233 args = unpack$i(args, 'hsv'); 1234 var h = args[0]; 1235 var s = args[1]; 1236 var v = args[2]; 1237 var r,g,b; 1238 v *= 255; 1239 if (s === 0) { 1240 r = g = b = v; 1241 } else { 1242 if (h === 360) { h = 0; } 1243 if (h > 360) { h -= 360; } 1244 if (h < 0) { h += 360; } 1245 h /= 60; 1246 1247 var i = floor$1(h); 1248 var f = h - i; 1249 var p = v * (1 - s); 1250 var q = v * (1 - s * f); 1251 var t = v * (1 - s * (1 - f)); 1252 1253 switch (i) { 1254 case 0: (assign = [v, t, p], r = assign[0], g = assign[1], b = assign[2]); break 1255 case 1: (assign$1 = [q, v, p], r = assign$1[0], g = assign$1[1], b = assign$1[2]); break 1256 case 2: (assign$2 = [p, v, t], r = assign$2[0], g = assign$2[1], b = assign$2[2]); break 1257 case 3: (assign$3 = [p, q, v], r = assign$3[0], g = assign$3[1], b = assign$3[2]); break 1258 case 4: (assign$4 = [t, p, v], r = assign$4[0], g = assign$4[1], b = assign$4[2]); break 1259 case 5: (assign$5 = [v, p, q], r = assign$5[0], g = assign$5[1], b = assign$5[2]); break 1260 } 1261 } 1262 return [r,g,b,args.length > 3?args[3]:1]; 1263 }; 1264 1265 var hsv2rgb_1 = hsv2rgb; 1266 1267 var unpack$j = utils.unpack; 1268 var type$8 = utils.type; 1269 1270 1271 1272 1273 1274 1275 Color_1.prototype.hsv = function() { 1276 return rgb2hsv(this._rgb); 1277 }; 1278 1279 chroma_1.hsv = function () { 1280 var args = [], len = arguments.length; 1281 while ( len-- ) args[ len ] = arguments[ len ]; 1282 1283 return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['hsv']) )); 1284 }; 1285 1286 input.format.hsv = hsv2rgb_1; 1287 1288 input.autodetect.push({ 1289 p: 2, 1290 test: function () { 1291 var args = [], len = arguments.length; 1292 while ( len-- ) args[ len ] = arguments[ len ]; 1293 1294 args = unpack$j(args, 'hsv'); 1295 if (type$8(args) === 'array' && args.length === 3) { 1296 return 'hsv'; 1297 } 1298 } 1299 }); 1300 1301 var labConstants = { 1302 // Corresponds roughly to RGB brighter/darker 1303 Kn: 18, 1304 1305 // D65 standard referent 1306 Xn: 0.950470, 1307 Yn: 1, 1308 Zn: 1.088830, 1309 1310 t0: 0.137931034, // 4 / 29 1311 t1: 0.206896552, // 6 / 29 1312 t2: 0.12841855, // 3 * t1 * t1 1313 t3: 0.008856452, // t1 * t1 * t1 1314 }; 1315 1316 var unpack$k = utils.unpack; 1317 var pow = Math.pow; 1318 1319 var rgb2lab = function () { 1320 var args = [], len = arguments.length; 1321 while ( len-- ) args[ len ] = arguments[ len ]; 1322 1323 var ref = unpack$k(args, 'rgb'); 1324 var r = ref[0]; 1325 var g = ref[1]; 1326 var b = ref[2]; 1327 var ref$1 = rgb2xyz(r,g,b); 1328 var x = ref$1[0]; 1329 var y = ref$1[1]; 1330 var z = ref$1[2]; 1331 var l = 116 * y - 16; 1332 return [l < 0 ? 0 : l, 500 * (x - y), 200 * (y - z)]; 1333 }; 1334 1335 var rgb_xyz = function (r) { 1336 if ((r /= 255) <= 0.04045) { return r / 12.92; } 1337 return pow((r + 0.055) / 1.055, 2.4); 1338 }; 1339 1340 var xyz_lab = function (t) { 1341 if (t > labConstants.t3) { return pow(t, 1 / 3); } 1342 return t / labConstants.t2 + labConstants.t0; 1343 }; 1344 1345 var rgb2xyz = function (r,g,b) { 1346 r = rgb_xyz(r); 1347 g = rgb_xyz(g); 1348 b = rgb_xyz(b); 1349 var x = xyz_lab((0.4124564 * r + 0.3575761 * g + 0.1804375 * b) / labConstants.Xn); 1350 var y = xyz_lab((0.2126729 * r + 0.7151522 * g + 0.0721750 * b) / labConstants.Yn); 1351 var z = xyz_lab((0.0193339 * r + 0.1191920 * g + 0.9503041 * b) / labConstants.Zn); 1352 return [x,y,z]; 1353 }; 1354 1355 var rgb2lab_1 = rgb2lab; 1356 1357 var unpack$l = utils.unpack; 1358 var pow$1 = Math.pow; 1359 1360 /* 1361 * L* [0..100] 1362 * a [-100..100] 1363 * b [-100..100] 1364 */ 1365 var lab2rgb = function () { 1366 var args = [], len = arguments.length; 1367 while ( len-- ) args[ len ] = arguments[ len ]; 1368 1369 args = unpack$l(args, 'lab'); 1370 var l = args[0]; 1371 var a = args[1]; 1372 var b = args[2]; 1373 var x,y,z, r,g,b_; 1374 1375 y = (l + 16) / 116; 1376 x = isNaN(a) ? y : y + a / 500; 1377 z = isNaN(b) ? y : y - b / 200; 1378 1379 y = labConstants.Yn * lab_xyz(y); 1380 x = labConstants.Xn * lab_xyz(x); 1381 z = labConstants.Zn * lab_xyz(z); 1382 1383 r = xyz_rgb(3.2404542 * x - 1.5371385 * y - 0.4985314 * z); // D65 -> sRGB 1384 g = xyz_rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z); 1385 b_ = xyz_rgb(0.0556434 * x - 0.2040259 * y + 1.0572252 * z); 1386 1387 return [r,g,b_,args.length > 3 ? args[3] : 1]; 1388 }; 1389 1390 var xyz_rgb = function (r) { 1391 return 255 * (r <= 0.00304 ? 12.92 * r : 1.055 * pow$1(r, 1 / 2.4) - 0.055) 1392 }; 1393 1394 var lab_xyz = function (t) { 1395 return t > labConstants.t1 ? t * t * t : labConstants.t2 * (t - labConstants.t0) 1396 }; 1397 1398 var lab2rgb_1 = lab2rgb; 1399 1400 var unpack$m = utils.unpack; 1401 var type$9 = utils.type; 1402 1403 1404 1405 1406 1407 1408 Color_1.prototype.lab = function() { 1409 return rgb2lab_1(this._rgb); 1410 }; 1411 1412 chroma_1.lab = function () { 1413 var args = [], len = arguments.length; 1414 while ( len-- ) args[ len ] = arguments[ len ]; 1415 1416 return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['lab']) )); 1417 }; 1418 1419 input.format.lab = lab2rgb_1; 1420 1421 input.autodetect.push({ 1422 p: 2, 1423 test: function () { 1424 var args = [], len = arguments.length; 1425 while ( len-- ) args[ len ] = arguments[ len ]; 1426 1427 args = unpack$m(args, 'lab'); 1428 if (type$9(args) === 'array' && args.length === 3) { 1429 return 'lab'; 1430 } 1431 } 1432 }); 1433 1434 var unpack$n = utils.unpack; 1435 var RAD2DEG = utils.RAD2DEG; 1436 var sqrt$1 = Math.sqrt; 1437 var atan2 = Math.atan2; 1438 var round$4 = Math.round; 1439 1440 var lab2lch = function () { 1441 var args = [], len = arguments.length; 1442 while ( len-- ) args[ len ] = arguments[ len ]; 1443 1444 var ref = unpack$n(args, 'lab'); 1445 var l = ref[0]; 1446 var a = ref[1]; 1447 var b = ref[2]; 1448 var c = sqrt$1(a * a + b * b); 1449 var h = (atan2(b, a) * RAD2DEG + 360) % 360; 1450 if (round$4(c*10000) === 0) { h = Number.NaN; } 1451 return [l, c, h]; 1452 }; 1453 1454 var lab2lch_1 = lab2lch; 1455 1456 var unpack$o = utils.unpack; 1457 1458 1459 1460 var rgb2lch = function () { 1461 var args = [], len = arguments.length; 1462 while ( len-- ) args[ len ] = arguments[ len ]; 1463 1464 var ref = unpack$o(args, 'rgb'); 1465 var r = ref[0]; 1466 var g = ref[1]; 1467 var b = ref[2]; 1468 var ref$1 = rgb2lab_1(r,g,b); 1469 var l = ref$1[0]; 1470 var a = ref$1[1]; 1471 var b_ = ref$1[2]; 1472 return lab2lch_1(l,a,b_); 1473 }; 1474 1475 var rgb2lch_1 = rgb2lch; 1476 1477 var unpack$p = utils.unpack; 1478 var DEG2RAD = utils.DEG2RAD; 1479 var sin = Math.sin; 1480 var cos$1 = Math.cos; 1481 1482 var lch2lab = function () { 1483 var args = [], len = arguments.length; 1484 while ( len-- ) args[ len ] = arguments[ len ]; 1485 1486 /* 1487 Convert from a qualitative parameter h and a quantitative parameter l to a 24-bit pixel. 1488 These formulas were invented by David Dalrymple to obtain maximum contrast without going 1489 out of gamut if the parameters are in the range 0-1. 1490 1491 A saturation multiplier was added by Gregor Aisch 1492 */ 1493 var ref = unpack$p(args, 'lch'); 1494 var l = ref[0]; 1495 var c = ref[1]; 1496 var h = ref[2]; 1497 if (isNaN(h)) { h = 0; } 1498 h = h * DEG2RAD; 1499 return [l, cos$1(h) * c, sin(h) * c] 1500 }; 1501 1502 var lch2lab_1 = lch2lab; 1503 1504 var unpack$q = utils.unpack; 1505 1506 1507 1508 var lch2rgb = function () { 1509 var args = [], len = arguments.length; 1510 while ( len-- ) args[ len ] = arguments[ len ]; 1511 1512 args = unpack$q(args, 'lch'); 1513 var l = args[0]; 1514 var c = args[1]; 1515 var h = args[2]; 1516 var ref = lch2lab_1 (l,c,h); 1517 var L = ref[0]; 1518 var a = ref[1]; 1519 var b_ = ref[2]; 1520 var ref$1 = lab2rgb_1 (L,a,b_); 1521 var r = ref$1[0]; 1522 var g = ref$1[1]; 1523 var b = ref$1[2]; 1524 return [r, g, b, args.length > 3 ? args[3] : 1]; 1525 }; 1526 1527 var lch2rgb_1 = lch2rgb; 1528 1529 var unpack$r = utils.unpack; 1530 1531 1532 var hcl2rgb = function () { 1533 var args = [], len = arguments.length; 1534 while ( len-- ) args[ len ] = arguments[ len ]; 1535 1536 var hcl = unpack$r(args, 'hcl').reverse(); 1537 return lch2rgb_1.apply(void 0, hcl); 1538 }; 1539 1540 var hcl2rgb_1 = hcl2rgb; 1541 1542 var unpack$s = utils.unpack; 1543 var type$a = utils.type; 1544 1545 1546 1547 1548 1549 1550 Color_1.prototype.lch = function() { return rgb2lch_1(this._rgb); }; 1551 Color_1.prototype.hcl = function() { return rgb2lch_1(this._rgb).reverse(); }; 1552 1553 chroma_1.lch = function () { 1554 var args = [], len = arguments.length; 1555 while ( len-- ) args[ len ] = arguments[ len ]; 1556 1557 return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['lch']) )); 1558 }; 1559 chroma_1.hcl = function () { 1560 var args = [], len = arguments.length; 1561 while ( len-- ) args[ len ] = arguments[ len ]; 1562 1563 return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['hcl']) )); 1564 }; 1565 1566 input.format.lch = lch2rgb_1; 1567 input.format.hcl = hcl2rgb_1; 1568 1569 ['lch','hcl'].forEach(function (m) { return input.autodetect.push({ 1570 p: 2, 1571 test: function () { 1572 var args = [], len = arguments.length; 1573 while ( len-- ) args[ len ] = arguments[ len ]; 1574 1575 args = unpack$s(args, m); 1576 if (type$a(args) === 'array' && args.length === 3) { 1577 return m; 1578 } 1579 } 1580 }); }); 1581 1582 /** 1583 X11 color names 1584 1585 http://www.w3.org/TR/css3-color/#svg-color 1586 */ 1587 1588 var w3cx11 = { 1589 aliceblue: '#f0f8ff', 1590 antiquewhite: '#faebd7', 1591 aqua: '#00ffff', 1592 aquamarine: '#7fffd4', 1593 azure: '#f0ffff', 1594 beige: '#f5f5dc', 1595 bisque: '#ffe4c4', 1596 black: '#000000', 1597 blanchedalmond: '#ffebcd', 1598 blue: '#0000ff', 1599 blueviolet: '#8a2be2', 1600 brown: '#a52a2a', 1601 burlywood: '#deb887', 1602 cadetblue: '#5f9ea0', 1603 chartreuse: '#7fff00', 1604 chocolate: '#d2691e', 1605 coral: '#ff7f50', 1606 cornflower: '#6495ed', 1607 cornflowerblue: '#6495ed', 1608 cornsilk: '#fff8dc', 1609 crimson: '#dc143c', 1610 cyan: '#00ffff', 1611 darkblue: '#00008b', 1612 darkcyan: '#008b8b', 1613 darkgoldenrod: '#b8860b', 1614 darkgray: '#a9a9a9', 1615 darkgreen: '#006400', 1616 darkgrey: '#a9a9a9', 1617 darkkhaki: '#bdb76b', 1618 darkmagenta: '#8b008b', 1619 darkolivegreen: '#556b2f', 1620 darkorange: '#ff8c00', 1621 darkorchid: '#9932cc', 1622 darkred: '#8b0000', 1623 darksalmon: '#e9967a', 1624 darkseagreen: '#8fbc8f', 1625 darkslateblue: '#483d8b', 1626 darkslategray: '#2f4f4f', 1627 darkslategrey: '#2f4f4f', 1628 darkturquoise: '#00ced1', 1629 darkviolet: '#9400d3', 1630 deeppink: '#ff1493', 1631 deepskyblue: '#00bfff', 1632 dimgray: '#696969', 1633 dimgrey: '#696969', 1634 dodgerblue: '#1e90ff', 1635 firebrick: '#b22222', 1636 floralwhite: '#fffaf0', 1637 forestgreen: '#228b22', 1638 fuchsia: '#ff00ff', 1639 gainsboro: '#dcdcdc', 1640 ghostwhite: '#f8f8ff', 1641 gold: '#ffd700', 1642 goldenrod: '#daa520', 1643 gray: '#808080', 1644 green: '#008000', 1645 greenyellow: '#adff2f', 1646 grey: '#808080', 1647 honeydew: '#f0fff0', 1648 hotpink: '#ff69b4', 1649 indianred: '#cd5c5c', 1650 indigo: '#4b0082', 1651 ivory: '#fffff0', 1652 khaki: '#f0e68c', 1653 laserlemon: '#ffff54', 1654 lavender: '#e6e6fa', 1655 lavenderblush: '#fff0f5', 1656 lawngreen: '#7cfc00', 1657 lemonchiffon: '#fffacd', 1658 lightblue: '#add8e6', 1659 lightcoral: '#f08080', 1660 lightcyan: '#e0ffff', 1661 lightgoldenrod: '#fafad2', 1662 lightgoldenrodyellow: '#fafad2', 1663 lightgray: '#d3d3d3', 1664 lightgreen: '#90ee90', 1665 lightgrey: '#d3d3d3', 1666 lightpink: '#ffb6c1', 1667 lightsalmon: '#ffa07a', 1668 lightseagreen: '#20b2aa', 1669 lightskyblue: '#87cefa', 1670 lightslategray: '#778899', 1671 lightslategrey: '#778899', 1672 lightsteelblue: '#b0c4de', 1673 lightyellow: '#ffffe0', 1674 lime: '#00ff00', 1675 limegreen: '#32cd32', 1676 linen: '#faf0e6', 1677 magenta: '#ff00ff', 1678 maroon: '#800000', 1679 maroon2: '#7f0000', 1680 maroon3: '#b03060', 1681 mediumaquamarine: '#66cdaa', 1682 mediumblue: '#0000cd', 1683 mediumorchid: '#ba55d3', 1684 mediumpurple: '#9370db', 1685 mediumseagreen: '#3cb371', 1686 mediumslateblue: '#7b68ee', 1687 mediumspringgreen: '#00fa9a', 1688 mediumturquoise: '#48d1cc', 1689 mediumvioletred: '#c71585', 1690 midnightblue: '#191970', 1691 mintcream: '#f5fffa', 1692 mistyrose: '#ffe4e1', 1693 moccasin: '#ffe4b5', 1694 navajowhite: '#ffdead', 1695 navy: '#000080', 1696 oldlace: '#fdf5e6', 1697 olive: '#808000', 1698 olivedrab: '#6b8e23', 1699 orange: '#ffa500', 1700 orangered: '#ff4500', 1701 orchid: '#da70d6', 1702 palegoldenrod: '#eee8aa', 1703 palegreen: '#98fb98', 1704 paleturquoise: '#afeeee', 1705 palevioletred: '#db7093', 1706 papayawhip: '#ffefd5', 1707 peachpuff: '#ffdab9', 1708 peru: '#cd853f', 1709 pink: '#ffc0cb', 1710 plum: '#dda0dd', 1711 powderblue: '#b0e0e6', 1712 purple: '#800080', 1713 purple2: '#7f007f', 1714 purple3: '#a020f0', 1715 rebeccapurple: '#663399', 1716 red: '#ff0000', 1717 rosybrown: '#bc8f8f', 1718 royalblue: '#4169e1', 1719 saddlebrown: '#8b4513', 1720 salmon: '#fa8072', 1721 sandybrown: '#f4a460', 1722 seagreen: '#2e8b57', 1723 seashell: '#fff5ee', 1724 sienna: '#a0522d', 1725 silver: '#c0c0c0', 1726 skyblue: '#87ceeb', 1727 slateblue: '#6a5acd', 1728 slategray: '#708090', 1729 slategrey: '#708090', 1730 snow: '#fffafa', 1731 springgreen: '#00ff7f', 1732 steelblue: '#4682b4', 1733 tan: '#d2b48c', 1734 teal: '#008080', 1735 thistle: '#d8bfd8', 1736 tomato: '#ff6347', 1737 turquoise: '#40e0d0', 1738 violet: '#ee82ee', 1739 wheat: '#f5deb3', 1740 white: '#ffffff', 1741 whitesmoke: '#f5f5f5', 1742 yellow: '#ffff00', 1743 yellowgreen: '#9acd32' 1744 }; 1745 1746 var w3cx11_1 = w3cx11; 1747 1748 var type$b = utils.type; 1749 1750 1751 1752 1753 1754 Color_1.prototype.name = function() { 1755 var hex = rgb2hex_1(this._rgb, 'rgb'); 1756 for (var i = 0, list = Object.keys(w3cx11_1); i < list.length; i += 1) { 1757 var n = list[i]; 1758 1759 if (w3cx11_1[n] === hex) { return n.toLowerCase(); } 1760 } 1761 return hex; 1762 }; 1763 1764 input.format.named = function (name) { 1765 name = name.toLowerCase(); 1766 if (w3cx11_1[name]) { return hex2rgb_1(w3cx11_1[name]); } 1767 throw new Error('unknown color name: '+name); 1768 }; 1769 1770 input.autodetect.push({ 1771 p: 5, 1772 test: function (h) { 1773 var rest = [], len = arguments.length - 1; 1774 while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ]; 1775 1776 if (!rest.length && type$b(h) === 'string' && w3cx11_1[h.toLowerCase()]) { 1777 return 'named'; 1778 } 1779 } 1780 }); 1781 1782 var unpack$t = utils.unpack; 1783 1784 var rgb2num = function () { 1785 var args = [], len = arguments.length; 1786 while ( len-- ) args[ len ] = arguments[ len ]; 1787 1788 var ref = unpack$t(args, 'rgb'); 1789 var r = ref[0]; 1790 var g = ref[1]; 1791 var b = ref[2]; 1792 return (r << 16) + (g << 8) + b; 1793 }; 1794 1795 var rgb2num_1 = rgb2num; 1796 1797 var type$c = utils.type; 1798 1799 var num2rgb = function (num) { 1800 if (type$c(num) == "number" && num >= 0 && num <= 0xFFFFFF) { 1801 var r = num >> 16; 1802 var g = (num >> 8) & 0xFF; 1803 var b = num & 0xFF; 1804 return [r,g,b,1]; 1805 } 1806 throw new Error("unknown num color: "+num); 1807 }; 1808 1809 var num2rgb_1 = num2rgb; 1810 1811 var type$d = utils.type; 1812 1813 1814 1815 Color_1.prototype.num = function() { 1816 return rgb2num_1(this._rgb); 1817 }; 1818 1819 chroma_1.num = function () { 1820 var args = [], len = arguments.length; 1821 while ( len-- ) args[ len ] = arguments[ len ]; 1822 1823 return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['num']) )); 1824 }; 1825 1826 input.format.num = num2rgb_1; 1827 1828 input.autodetect.push({ 1829 p: 5, 1830 test: function () { 1831 var args = [], len = arguments.length; 1832 while ( len-- ) args[ len ] = arguments[ len ]; 1833 1834 if (args.length === 1 && type$d(args[0]) === 'number' && args[0] >= 0 && args[0] <= 0xFFFFFF) { 1835 return 'num'; 1836 } 1837 } 1838 }); 1839 1840 var unpack$u = utils.unpack; 1841 var type$e = utils.type; 1842 var round$5 = Math.round; 1843 1844 Color_1.prototype.rgb = function(rnd) { 1845 if ( rnd === void 0 ) rnd=true; 1846 1847 if (rnd === false) { return this._rgb.slice(0,3); } 1848 return this._rgb.slice(0,3).map(round$5); 1849 }; 1850 1851 Color_1.prototype.rgba = function(rnd) { 1852 if ( rnd === void 0 ) rnd=true; 1853 1854 return this._rgb.slice(0,4).map(function (v,i) { 1855 return i<3 ? (rnd === false ? v : round$5(v)) : v; 1856 }); 1857 }; 1858 1859 chroma_1.rgb = function () { 1860 var args = [], len = arguments.length; 1861 while ( len-- ) args[ len ] = arguments[ len ]; 1862 1863 return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['rgb']) )); 1864 }; 1865 1866 input.format.rgb = function () { 1867 var args = [], len = arguments.length; 1868 while ( len-- ) args[ len ] = arguments[ len ]; 1869 1870 var rgba = unpack$u(args, 'rgba'); 1871 if (rgba[3] === undefined) { rgba[3] = 1; } 1872 return rgba; 1873 }; 1874 1875 input.autodetect.push({ 1876 p: 3, 1877 test: function () { 1878 var args = [], len = arguments.length; 1879 while ( len-- ) args[ len ] = arguments[ len ]; 1880 1881 args = unpack$u(args, 'rgba'); 1882 if (type$e(args) === 'array' && (args.length === 3 || 1883 args.length === 4 && type$e(args[3]) == 'number' && args[3] >= 0 && args[3] <= 1)) { 1884 return 'rgb'; 1885 } 1886 } 1887 }); 1888 1889 /* 1890 * Based on implementation by Neil Bartlett 1891 * https://github.com/neilbartlett/color-temperature 1892 */ 1893 1894 var log = Math.log; 1895 1896 var temperature2rgb = function (kelvin) { 1897 var temp = kelvin / 100; 1898 var r,g,b; 1899 if (temp < 66) { 1900 r = 255; 1901 g = -155.25485562709179 - 0.44596950469579133 * (g = temp-2) + 104.49216199393888 * log(g); 1902 b = temp < 20 ? 0 : -254.76935184120902 + 0.8274096064007395 * (b = temp-10) + 115.67994401066147 * log(b); 1903 } else { 1904 r = 351.97690566805693 + 0.114206453784165 * (r = temp-55) - 40.25366309332127 * log(r); 1905 g = 325.4494125711974 + 0.07943456536662342 * (g = temp-50) - 28.0852963507957 * log(g); 1906 b = 255; 1907 } 1908 return [r,g,b,1]; 1909 }; 1910 1911 var temperature2rgb_1 = temperature2rgb; 1912 1913 /* 1914 * Based on implementation by Neil Bartlett 1915 * https://github.com/neilbartlett/color-temperature 1916 **/ 1917 1918 1919 var unpack$v = utils.unpack; 1920 var round$6 = Math.round; 1921 1922 var rgb2temperature = function () { 1923 var args = [], len = arguments.length; 1924 while ( len-- ) args[ len ] = arguments[ len ]; 1925 1926 var rgb = unpack$v(args, 'rgb'); 1927 var r = rgb[0], b = rgb[2]; 1928 var minTemp = 1000; 1929 var maxTemp = 40000; 1930 var eps = 0.4; 1931 var temp; 1932 while (maxTemp - minTemp > eps) { 1933 temp = (maxTemp + minTemp) * 0.5; 1934 var rgb$1 = temperature2rgb_1(temp); 1935 if ((rgb$1[2] / rgb$1[0]) >= (b / r)) { 1936 maxTemp = temp; 1937 } else { 1938 minTemp = temp; 1939 } 1940 } 1941 return round$6(temp); 1942 }; 1943 1944 var rgb2temperature_1 = rgb2temperature; 1945 1946 Color_1.prototype.temp = 1947 Color_1.prototype.kelvin = 1948 Color_1.prototype.temperature = function() { 1949 return rgb2temperature_1(this._rgb); 1950 }; 1951 1952 chroma_1.temp = 1953 chroma_1.kelvin = 1954 chroma_1.temperature = function () { 1955 var args = [], len = arguments.length; 1956 while ( len-- ) args[ len ] = arguments[ len ]; 1957 1958 return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['temp']) )); 1959 }; 1960 1961 input.format.temp = 1962 input.format.kelvin = 1963 input.format.temperature = temperature2rgb_1; 1964 1965 var type$f = utils.type; 1966 1967 Color_1.prototype.alpha = function(a, mutate) { 1968 if ( mutate === void 0 ) mutate=false; 1969 1970 if (a !== undefined && type$f(a) === 'number') { 1971 if (mutate) { 1972 this._rgb[3] = a; 1973 return this; 1974 } 1975 return new Color_1([this._rgb[0], this._rgb[1], this._rgb[2], a], 'rgb'); 1976 } 1977 return this._rgb[3]; 1978 }; 1979 1980 Color_1.prototype.clipped = function() { 1981 return this._rgb._clipped || false; 1982 }; 1983 1984 Color_1.prototype.darken = function(amount) { 1985 if ( amount === void 0 ) amount=1; 1986 1987 var me = this; 1988 var lab = me.lab(); 1989 lab[0] -= labConstants.Kn * amount; 1990 return new Color_1(lab, 'lab').alpha(me.alpha(), true); 1991 }; 1992 1993 Color_1.prototype.brighten = function(amount) { 1994 if ( amount === void 0 ) amount=1; 1995 1996 return this.darken(-amount); 1997 }; 1998 1999 Color_1.prototype.darker = Color_1.prototype.darken; 2000 Color_1.prototype.brighter = Color_1.prototype.brighten; 2001 2002 Color_1.prototype.get = function(mc) { 2003 var ref = mc.split('.'); 2004 var mode = ref[0]; 2005 var channel = ref[1]; 2006 var src = this[mode](); 2007 if (channel) { 2008 var i = mode.indexOf(channel); 2009 if (i > -1) { return src[i]; } 2010 throw new Error(("unknown channel " + channel + " in mode " + mode)); 2011 } else { 2012 return src; 2013 } 2014 }; 2015 2016 var type$g = utils.type; 2017 var pow$2 = Math.pow; 2018 2019 var EPS = 1e-7; 2020 var MAX_ITER = 20; 2021 2022 Color_1.prototype.luminance = function(lum) { 2023 if (lum !== undefined && type$g(lum) === 'number') { 2024 if (lum === 0) { 2025 // return pure black 2026 return new Color_1([0,0,0,this._rgb[3]], 'rgb'); 2027 } 2028 if (lum === 1) { 2029 // return pure white 2030 return new Color_1([255,255,255,this._rgb[3]], 'rgb'); 2031 } 2032 // compute new color using... 2033 var cur_lum = this.luminance(); 2034 var mode = 'rgb'; 2035 var max_iter = MAX_ITER; 2036 2037 var test = function (low, high) { 2038 var mid = low.interpolate(high, 0.5, mode); 2039 var lm = mid.luminance(); 2040 if (Math.abs(lum - lm) < EPS || !max_iter--) { 2041 // close enough 2042 return mid; 2043 } 2044 return lm > lum ? test(low, mid) : test(mid, high); 2045 }; 2046 2047 var rgb = (cur_lum > lum ? test(new Color_1([0,0,0]), this) : test(this, new Color_1([255,255,255]))).rgb(); 2048 return new Color_1(rgb.concat( [this._rgb[3]])); 2049 } 2050 return rgb2luminance.apply(void 0, (this._rgb).slice(0,3)); 2051 }; 2052 2053 2054 var rgb2luminance = function (r,g,b) { 2055 // relative luminance 2056 // see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef 2057 r = luminance_x(r); 2058 g = luminance_x(g); 2059 b = luminance_x(b); 2060 return 0.2126 * r + 0.7152 * g + 0.0722 * b; 2061 }; 2062 2063 var luminance_x = function (x) { 2064 x /= 255; 2065 return x <= 0.03928 ? x/12.92 : pow$2((x+0.055)/1.055, 2.4); 2066 }; 2067 2068 var interpolator = {}; 2069 2070 var type$h = utils.type; 2071 2072 2073 var mix = function (col1, col2, f) { 2074 if ( f === void 0 ) f=0.5; 2075 var rest = [], len = arguments.length - 3; 2076 while ( len-- > 0 ) rest[ len ] = arguments[ len + 3 ]; 2077 2078 var mode = rest[0] || 'lrgb'; 2079 if (!interpolator[mode] && !rest.length) { 2080 // fall back to the first supported mode 2081 mode = Object.keys(interpolator)[0]; 2082 } 2083 if (!interpolator[mode]) { 2084 throw new Error(("interpolation mode " + mode + " is not defined")); 2085 } 2086 if (type$h(col1) !== 'object') { col1 = new Color_1(col1); } 2087 if (type$h(col2) !== 'object') { col2 = new Color_1(col2); } 2088 return interpolator[mode](col1, col2, f) 2089 .alpha(col1.alpha() + f * (col2.alpha() - col1.alpha())); 2090 }; 2091 2092 Color_1.prototype.mix = 2093 Color_1.prototype.interpolate = function(col2, f) { 2094 if ( f === void 0 ) f=0.5; 2095 var rest = [], len = arguments.length - 2; 2096 while ( len-- > 0 ) rest[ len ] = arguments[ len + 2 ]; 2097 2098 return mix.apply(void 0, [ this, col2, f ].concat( rest )); 2099 }; 2100 2101 Color_1.prototype.premultiply = function(mutate) { 2102 if ( mutate === void 0 ) mutate=false; 2103 2104 var rgb = this._rgb; 2105 var a = rgb[3]; 2106 if (mutate) { 2107 this._rgb = [rgb[0]*a, rgb[1]*a, rgb[2]*a, a]; 2108 return this; 2109 } else { 2110 return new Color_1([rgb[0]*a, rgb[1]*a, rgb[2]*a, a], 'rgb'); 2111 } 2112 }; 2113 2114 Color_1.prototype.saturate = function(amount) { 2115 if ( amount === void 0 ) amount=1; 2116 2117 var me = this; 2118 var lch = me.lch(); 2119 lch[1] += labConstants.Kn * amount; 2120 if (lch[1] < 0) { lch[1] = 0; } 2121 return new Color_1(lch, 'lch').alpha(me.alpha(), true); 2122 }; 2123 2124 Color_1.prototype.desaturate = function(amount) { 2125 if ( amount === void 0 ) amount=1; 2126 2127 return this.saturate(-amount); 2128 }; 2129 2130 var type$i = utils.type; 2131 2132 Color_1.prototype.set = function(mc, value, mutate) { 2133 if ( mutate === void 0 ) mutate=false; 2134 2135 var ref = mc.split('.'); 2136 var mode = ref[0]; 2137 var channel = ref[1]; 2138 var src = this[mode](); 2139 if (channel) { 2140 var i = mode.indexOf(channel); 2141 if (i > -1) { 2142 if (type$i(value) == 'string') { 2143 switch(value.charAt(0)) { 2144 case '+': src[i] += +value; break; 2145 case '-': src[i] += +value; break; 2146 case '*': src[i] *= +(value.substr(1)); break; 2147 case '/': src[i] /= +(value.substr(1)); break; 2148 default: src[i] = +value; 2149 } 2150 } else if (type$i(value) === 'number') { 2151 src[i] = value; 2152 } else { 2153 throw new Error("unsupported value for Color.set"); 2154 } 2155 var out = new Color_1(src, mode); 2156 if (mutate) { 2157 this._rgb = out._rgb; 2158 return this; 2159 } 2160 return out; 2161 } 2162 throw new Error(("unknown channel " + channel + " in mode " + mode)); 2163 } else { 2164 return src; 2165 } 2166 }; 2167 2168 var rgb$1 = function (col1, col2, f) { 2169 var xyz0 = col1._rgb; 2170 var xyz1 = col2._rgb; 2171 return new Color_1( 2172 xyz0[0] + f * (xyz1[0]-xyz0[0]), 2173 xyz0[1] + f * (xyz1[1]-xyz0[1]), 2174 xyz0[2] + f * (xyz1[2]-xyz0[2]), 2175 'rgb' 2176 ) 2177 }; 2178 2179 // register interpolator 2180 interpolator.rgb = rgb$1; 2181 2182 var sqrt$2 = Math.sqrt; 2183 var pow$3 = Math.pow; 2184 2185 var lrgb = function (col1, col2, f) { 2186 var ref = col1._rgb; 2187 var x1 = ref[0]; 2188 var y1 = ref[1]; 2189 var z1 = ref[2]; 2190 var ref$1 = col2._rgb; 2191 var x2 = ref$1[0]; 2192 var y2 = ref$1[1]; 2193 var z2 = ref$1[2]; 2194 return new Color_1( 2195 sqrt$2(pow$3(x1,2) * (1-f) + pow$3(x2,2) * f), 2196 sqrt$2(pow$3(y1,2) * (1-f) + pow$3(y2,2) * f), 2197 sqrt$2(pow$3(z1,2) * (1-f) + pow$3(z2,2) * f), 2198 'rgb' 2199 ) 2200 }; 2201 2202 // register interpolator 2203 interpolator.lrgb = lrgb; 2204 2205 var lab$1 = function (col1, col2, f) { 2206 var xyz0 = col1.lab(); 2207 var xyz1 = col2.lab(); 2208 return new Color_1( 2209 xyz0[0] + f * (xyz1[0]-xyz0[0]), 2210 xyz0[1] + f * (xyz1[1]-xyz0[1]), 2211 xyz0[2] + f * (xyz1[2]-xyz0[2]), 2212 'lab' 2213 ) 2214 }; 2215 2216 // register interpolator 2217 interpolator.lab = lab$1; 2218 2219 var _hsx = function (col1, col2, f, m) { 2220 var assign, assign$1; 2221 2222 var xyz0, xyz1; 2223 if (m === 'hsl') { 2224 xyz0 = col1.hsl(); 2225 xyz1 = col2.hsl(); 2226 } else if (m === 'hsv') { 2227 xyz0 = col1.hsv(); 2228 xyz1 = col2.hsv(); 2229 } else if (m === 'hcg') { 2230 xyz0 = col1.hcg(); 2231 xyz1 = col2.hcg(); 2232 } else if (m === 'hsi') { 2233 xyz0 = col1.hsi(); 2234 xyz1 = col2.hsi(); 2235 } else if (m === 'lch' || m === 'hcl') { 2236 m = 'hcl'; 2237 xyz0 = col1.hcl(); 2238 xyz1 = col2.hcl(); 2239 } 2240 2241 var hue0, hue1, sat0, sat1, lbv0, lbv1; 2242 if (m.substr(0, 1) === 'h') { 2243 (assign = xyz0, hue0 = assign[0], sat0 = assign[1], lbv0 = assign[2]); 2244 (assign$1 = xyz1, hue1 = assign$1[0], sat1 = assign$1[1], lbv1 = assign$1[2]); 2245 } 2246 2247 var sat, hue, lbv, dh; 2248 2249 if (!isNaN(hue0) && !isNaN(hue1)) { 2250 // both colors have hue 2251 if (hue1 > hue0 && hue1 - hue0 > 180) { 2252 dh = hue1-(hue0+360); 2253 } else if (hue1 < hue0 && hue0 - hue1 > 180) { 2254 dh = hue1+360-hue0; 2255 } else { 2256 dh = hue1 - hue0; 2257 } 2258 hue = hue0 + f * dh; 2259 } else if (!isNaN(hue0)) { 2260 hue = hue0; 2261 if ((lbv1 == 1 || lbv1 == 0) && m != 'hsv') { sat = sat0; } 2262 } else if (!isNaN(hue1)) { 2263 hue = hue1; 2264 if ((lbv0 == 1 || lbv0 == 0) && m != 'hsv') { sat = sat1; } 2265 } else { 2266 hue = Number.NaN; 2267 } 2268 2269 if (sat === undefined) { sat = sat0 + f * (sat1 - sat0); } 2270 lbv = lbv0 + f * (lbv1-lbv0); 2271 return new Color_1([hue, sat, lbv], m); 2272 }; 2273 2274 var lch$1 = function (col1, col2, f) { 2275 return _hsx(col1, col2, f, 'lch'); 2276 }; 2277 2278 // register interpolator 2279 interpolator.lch = lch$1; 2280 interpolator.hcl = lch$1; 2281 2282 var num$1 = function (col1, col2, f) { 2283 var c1 = col1.num(); 2284 var c2 = col2.num(); 2285 return new Color_1(c1 + f * (c2-c1), 'num') 2286 }; 2287 2288 // register interpolator 2289 interpolator.num = num$1; 2290 2291 var hcg$1 = function (col1, col2, f) { 2292 return _hsx(col1, col2, f, 'hcg'); 2293 }; 2294 2295 // register interpolator 2296 interpolator.hcg = hcg$1; 2297 2298 var hsi$1 = function (col1, col2, f) { 2299 return _hsx(col1, col2, f, 'hsi'); 2300 }; 2301 2302 // register interpolator 2303 interpolator.hsi = hsi$1; 2304 2305 var hsl$1 = function (col1, col2, f) { 2306 return _hsx(col1, col2, f, 'hsl'); 2307 }; 2308 2309 // register interpolator 2310 interpolator.hsl = hsl$1; 2311 2312 var hsv$1 = function (col1, col2, f) { 2313 return _hsx(col1, col2, f, 'hsv'); 2314 }; 2315 2316 // register interpolator 2317 interpolator.hsv = hsv$1; 2318 2319 var clip_rgb$2 = utils.clip_rgb; 2320 var pow$4 = Math.pow; 2321 var sqrt$3 = Math.sqrt; 2322 var PI$1 = Math.PI; 2323 var cos$2 = Math.cos; 2324 var sin$1 = Math.sin; 2325 var atan2$1 = Math.atan2; 2326 2327 var average = function (colors, mode, weights) { 2328 if ( mode === void 0 ) mode='lrgb'; 2329 if ( weights === void 0 ) weights=null; 2330 2331 var l = colors.length; 2332 if (!weights) { weights = Array.from(new Array(l)).map(function () { return 1; }); } 2333 // normalize weights 2334 var k = l / weights.reduce(function(a, b) { return a + b; }); 2335 weights.forEach(function (w,i) { weights[i] *= k; }); 2336 // convert colors to Color objects 2337 colors = colors.map(function (c) { return new Color_1(c); }); 2338 if (mode === 'lrgb') { 2339 return _average_lrgb(colors, weights) 2340 } 2341 var first = colors.shift(); 2342 var xyz = first.get(mode); 2343 var cnt = []; 2344 var dx = 0; 2345 var dy = 0; 2346 // initial color 2347 for (var i=0; i<xyz.length; i++) { 2348 xyz[i] = (xyz[i] || 0) * weights[0]; 2349 cnt.push(isNaN(xyz[i]) ? 0 : weights[0]); 2350 if (mode.charAt(i) === 'h' && !isNaN(xyz[i])) { 2351 var A = xyz[i] / 180 * PI$1; 2352 dx += cos$2(A) * weights[0]; 2353 dy += sin$1(A) * weights[0]; 2354 } 2355 } 2356 2357 var alpha = first.alpha() * weights[0]; 2358 colors.forEach(function (c,ci) { 2359 var xyz2 = c.get(mode); 2360 alpha += c.alpha() * weights[ci+1]; 2361 for (var i=0; i<xyz.length; i++) { 2362 if (!isNaN(xyz2[i])) { 2363 cnt[i] += weights[ci+1]; 2364 if (mode.charAt(i) === 'h') { 2365 var A = xyz2[i] / 180 * PI$1; 2366 dx += cos$2(A) * weights[ci+1]; 2367 dy += sin$1(A) * weights[ci+1]; 2368 } else { 2369 xyz[i] += xyz2[i] * weights[ci+1]; 2370 } 2371 } 2372 } 2373 }); 2374 2375 for (var i$1=0; i$1<xyz.length; i$1++) { 2376 if (mode.charAt(i$1) === 'h') { 2377 var A$1 = atan2$1(dy / cnt[i$1], dx / cnt[i$1]) / PI$1 * 180; 2378 while (A$1 < 0) { A$1 += 360; } 2379 while (A$1 >= 360) { A$1 -= 360; } 2380 xyz[i$1] = A$1; 2381 } else { 2382 xyz[i$1] = xyz[i$1]/cnt[i$1]; 2383 } 2384 } 2385 alpha /= l; 2386 return (new Color_1(xyz, mode)).alpha(alpha > 0.99999 ? 1 : alpha, true); 2387 }; 2388 2389 2390 var _average_lrgb = function (colors, weights) { 2391 var l = colors.length; 2392 var xyz = [0,0,0,0]; 2393 for (var i=0; i < colors.length; i++) { 2394 var col = colors[i]; 2395 var f = weights[i] / l; 2396 var rgb = col._rgb; 2397 xyz[0] += pow$4(rgb[0],2) * f; 2398 xyz[1] += pow$4(rgb[1],2) * f; 2399 xyz[2] += pow$4(rgb[2],2) * f; 2400 xyz[3] += rgb[3] * f; 2401 } 2402 xyz[0] = sqrt$3(xyz[0]); 2403 xyz[1] = sqrt$3(xyz[1]); 2404 xyz[2] = sqrt$3(xyz[2]); 2405 if (xyz[3] > 0.9999999) { xyz[3] = 1; } 2406 return new Color_1(clip_rgb$2(xyz)); 2407 }; 2408 2409 // minimal multi-purpose interface 2410 2411 // @requires utils color analyze 2412 2413 2414 var type$j = utils.type; 2415 2416 var pow$5 = Math.pow; 2417 2418 var scale = function(colors) { 2419 2420 // constructor 2421 var _mode = 'rgb'; 2422 var _nacol = chroma_1('#ccc'); 2423 var _spread = 0; 2424 // const _fixed = false; 2425 var _domain = [0, 1]; 2426 var _pos = []; 2427 var _padding = [0,0]; 2428 var _classes = false; 2429 var _colors = []; 2430 var _out = false; 2431 var _min = 0; 2432 var _max = 1; 2433 var _correctLightness = false; 2434 var _colorCache = {}; 2435 var _useCache = true; 2436 var _gamma = 1; 2437 2438 // private methods 2439 2440 var setColors = function(colors) { 2441 colors = colors || ['#fff', '#000']; 2442 if (colors && type$j(colors) === 'string' && chroma_1.brewer && 2443 chroma_1.brewer[colors.toLowerCase()]) { 2444 colors = chroma_1.brewer[colors.toLowerCase()]; 2445 } 2446 if (type$j(colors) === 'array') { 2447 // handle single color 2448 if (colors.length === 1) { 2449 colors = [colors[0], colors[0]]; 2450 } 2451 // make a copy of the colors 2452 colors = colors.slice(0); 2453 // convert to chroma classes 2454 for (var c=0; c<colors.length; c++) { 2455 colors[c] = chroma_1(colors[c]); 2456 } 2457 // auto-fill color position 2458 _pos.length = 0; 2459 for (var c$1=0; c$1<colors.length; c$1++) { 2460 _pos.push(c$1/(colors.length-1)); 2461 } 2462 } 2463 resetCache(); 2464 return _colors = colors; 2465 }; 2466 2467 var getClass = function(value) { 2468 if (_classes != null) { 2469 var n = _classes.length-1; 2470 var i = 0; 2471 while (i < n && value >= _classes[i]) { 2472 i++; 2473 } 2474 return i-1; 2475 } 2476 return 0; 2477 }; 2478 2479 var tMapLightness = function (t) { return t; }; 2480 var tMapDomain = function (t) { return t; }; 2481 2482 // const classifyValue = function(value) { 2483 // let val = value; 2484 // if (_classes.length > 2) { 2485 // const n = _classes.length-1; 2486 // const i = getClass(value); 2487 // const minc = _classes[0] + ((_classes[1]-_classes[0]) * (0 + (_spread * 0.5))); // center of 1st class 2488 // const maxc = _classes[n-1] + ((_classes[n]-_classes[n-1]) * (1 - (_spread * 0.5))); // center of last class 2489 // val = _min + ((((_classes[i] + ((_classes[i+1] - _classes[i]) * 0.5)) - minc) / (maxc-minc)) * (_max - _min)); 2490 // } 2491 // return val; 2492 // }; 2493 2494 var getColor = function(val, bypassMap) { 2495 var col, t; 2496 if (bypassMap == null) { bypassMap = false; } 2497 if (isNaN(val) || (val === null)) { return _nacol; } 2498 if (!bypassMap) { 2499 if (_classes && (_classes.length > 2)) { 2500 // find the class 2501 var c = getClass(val); 2502 t = c / (_classes.length-2); 2503 } else if (_max !== _min) { 2504 // just interpolate between min/max 2505 t = (val - _min) / (_max - _min); 2506 } else { 2507 t = 1; 2508 } 2509 } else { 2510 t = val; 2511 } 2512 2513 // domain map 2514 t = tMapDomain(t); 2515 2516 if (!bypassMap) { 2517 t = tMapLightness(t); // lightness correction 2518 } 2519 2520 if (_gamma !== 1) { t = pow$5(t, _gamma); } 2521 2522 t = _padding[0] + (t * (1 - _padding[0] - _padding[1])); 2523 2524 t = Math.min(1, Math.max(0, t)); 2525 2526 var k = Math.floor(t * 10000); 2527 2528 if (_useCache && _colorCache[k]) { 2529 col = _colorCache[k]; 2530 } else { 2531 if (type$j(_colors) === 'array') { 2532 //for i in [0.._pos.length-1] 2533 for (var i=0; i<_pos.length; i++) { 2534 var p = _pos[i]; 2535 if (t <= p) { 2536 col = _colors[i]; 2537 break; 2538 } 2539 if ((t >= p) && (i === (_pos.length-1))) { 2540 col = _colors[i]; 2541 break; 2542 } 2543 if (t > p && t < _pos[i+1]) { 2544 t = (t-p)/(_pos[i+1]-p); 2545 col = chroma_1.interpolate(_colors[i], _colors[i+1], t, _mode); 2546 break; 2547 } 2548 } 2549 } else if (type$j(_colors) === 'function') { 2550 col = _colors(t); 2551 } 2552 if (_useCache) { _colorCache[k] = col; } 2553 } 2554 return col; 2555 }; 2556 2557 var resetCache = function () { return _colorCache = {}; }; 2558 2559 setColors(colors); 2560 2561 // public interface 2562 2563 var f = function(v) { 2564 var c = chroma_1(getColor(v)); 2565 if (_out && c[_out]) { return c[_out](); } else { return c; } 2566 }; 2567 2568 f.classes = function(classes) { 2569 if (classes != null) { 2570 if (type$j(classes) === 'array') { 2571 _classes = classes; 2572 _domain = [classes[0], classes[classes.length-1]]; 2573 } else { 2574 var d = chroma_1.analyze(_domain); 2575 if (classes === 0) { 2576 _classes = [d.min, d.max]; 2577 } else { 2578 _classes = chroma_1.limits(d, 'e', classes); 2579 } 2580 } 2581 return f; 2582 } 2583 return _classes; 2584 }; 2585 2586 2587 f.domain = function(domain) { 2588 if (!arguments.length) { 2589 return _domain; 2590 } 2591 _min = domain[0]; 2592 _max = domain[domain.length-1]; 2593 _pos = []; 2594 var k = _colors.length; 2595 if ((domain.length === k) && (_min !== _max)) { 2596 // update positions 2597 for (var i = 0, list = Array.from(domain); i < list.length; i += 1) { 2598 var d = list[i]; 2599 2600 _pos.push((d-_min) / (_max-_min)); 2601 } 2602 } else { 2603 for (var c=0; c<k; c++) { 2604 _pos.push(c/(k-1)); 2605 } 2606 if (domain.length > 2) { 2607 // set domain map 2608 var tOut = domain.map(function (d,i) { return i/(domain.length-1); }); 2609 var tBreaks = domain.map(function (d) { return (d - _min) / (_max - _min); }); 2610 if (!tBreaks.every(function (val, i) { return tOut[i] === val; })) { 2611 tMapDomain = function (t) { 2612 if (t <= 0 || t >= 1) { return t; } 2613 var i = 0; 2614 while (t >= tBreaks[i+1]) { i++; } 2615 var f = (t - tBreaks[i]) / (tBreaks[i+1] - tBreaks[i]); 2616 var out = tOut[i] + f * (tOut[i+1] - tOut[i]); 2617 return out; 2618 }; 2619 } 2620 2621 } 2622 } 2623 _domain = [_min, _max]; 2624 return f; 2625 }; 2626 2627 f.mode = function(_m) { 2628 if (!arguments.length) { 2629 return _mode; 2630 } 2631 _mode = _m; 2632 resetCache(); 2633 return f; 2634 }; 2635 2636 f.range = function(colors, _pos) { 2637 setColors(colors); 2638 return f; 2639 }; 2640 2641 f.out = function(_o) { 2642 _out = _o; 2643 return f; 2644 }; 2645 2646 f.spread = function(val) { 2647 if (!arguments.length) { 2648 return _spread; 2649 } 2650 _spread = val; 2651 return f; 2652 }; 2653 2654 f.correctLightness = function(v) { 2655 if (v == null) { v = true; } 2656 _correctLightness = v; 2657 resetCache(); 2658 if (_correctLightness) { 2659 tMapLightness = function(t) { 2660 var L0 = getColor(0, true).lab()[0]; 2661 var L1 = getColor(1, true).lab()[0]; 2662 var pol = L0 > L1; 2663 var L_actual = getColor(t, true).lab()[0]; 2664 var L_ideal = L0 + ((L1 - L0) * t); 2665 var L_diff = L_actual - L_ideal; 2666 var t0 = 0; 2667 var t1 = 1; 2668 var max_iter = 20; 2669 while ((Math.abs(L_diff) > 1e-2) && (max_iter-- > 0)) { 2670 (function() { 2671 if (pol) { L_diff *= -1; } 2672 if (L_diff < 0) { 2673 t0 = t; 2674 t += (t1 - t) * 0.5; 2675 } else { 2676 t1 = t; 2677 t += (t0 - t) * 0.5; 2678 } 2679 L_actual = getColor(t, true).lab()[0]; 2680 return L_diff = L_actual - L_ideal; 2681 })(); 2682 } 2683 return t; 2684 }; 2685 } else { 2686 tMapLightness = function (t) { return t; }; 2687 } 2688 return f; 2689 }; 2690 2691 f.padding = function(p) { 2692 if (p != null) { 2693 if (type$j(p) === 'number') { 2694 p = [p,p]; 2695 } 2696 _padding = p; 2697 return f; 2698 } else { 2699 return _padding; 2700 } 2701 }; 2702 2703 f.colors = function(numColors, out) { 2704 // If no arguments are given, return the original colors that were provided 2705 if (arguments.length < 2) { out = 'hex'; } 2706 var result = []; 2707 2708 if (arguments.length === 0) { 2709 result = _colors.slice(0); 2710 2711 } else if (numColors === 1) { 2712 result = [f(0.5)]; 2713 2714 } else if (numColors > 1) { 2715 var dm = _domain[0]; 2716 var dd = _domain[1] - dm; 2717 result = __range__(0, numColors, false).map(function (i) { return f( dm + ((i/(numColors-1)) * dd) ); }); 2718 2719 } else { // returns all colors based on the defined classes 2720 colors = []; 2721 var samples = []; 2722 if (_classes && (_classes.length > 2)) { 2723 for (var i = 1, end = _classes.length, asc = 1 <= end; asc ? i < end : i > end; asc ? i++ : i--) { 2724 samples.push((_classes[i-1]+_classes[i])*0.5); 2725 } 2726 } else { 2727 samples = _domain; 2728 } 2729 result = samples.map(function (v) { return f(v); }); 2730 } 2731 2732 if (chroma_1[out]) { 2733 result = result.map(function (c) { return c[out](); }); 2734 } 2735 return result; 2736 }; 2737 2738 f.cache = function(c) { 2739 if (c != null) { 2740 _useCache = c; 2741 return f; 2742 } else { 2743 return _useCache; 2744 } 2745 }; 2746 2747 f.gamma = function(g) { 2748 if (g != null) { 2749 _gamma = g; 2750 return f; 2751 } else { 2752 return _gamma; 2753 } 2754 }; 2755 2756 f.nodata = function(d) { 2757 if (d != null) { 2758 _nacol = chroma_1(d); 2759 return f; 2760 } else { 2761 return _nacol; 2762 } 2763 }; 2764 2765 return f; 2766 }; 2767 2768 function __range__(left, right, inclusive) { 2769 var range = []; 2770 var ascending = left < right; 2771 var end = !inclusive ? right : ascending ? right + 1 : right - 1; 2772 for (var i = left; ascending ? i < end : i > end; ascending ? i++ : i--) { 2773 range.push(i); 2774 } 2775 return range; 2776 } 2777 2778 // 2779 // interpolates between a set of colors uzing a bezier spline 2780 // 2781 2782 // @requires utils lab 2783 2784 2785 2786 2787 var bezier = function(colors) { 2788 var assign, assign$1, assign$2; 2789 2790 var I, lab0, lab1, lab2; 2791 colors = colors.map(function (c) { return new Color_1(c); }); 2792 if (colors.length === 2) { 2793 // linear interpolation 2794 (assign = colors.map(function (c) { return c.lab(); }), lab0 = assign[0], lab1 = assign[1]); 2795 I = function(t) { 2796 var lab = ([0, 1, 2].map(function (i) { return lab0[i] + (t * (lab1[i] - lab0[i])); })); 2797 return new Color_1(lab, 'lab'); 2798 }; 2799 } else if (colors.length === 3) { 2800 // quadratic bezier interpolation 2801 (assign$1 = colors.map(function (c) { return c.lab(); }), lab0 = assign$1[0], lab1 = assign$1[1], lab2 = assign$1[2]); 2802 I = function(t) { 2803 var lab = ([0, 1, 2].map(function (i) { return ((1-t)*(1-t) * lab0[i]) + (2 * (1-t) * t * lab1[i]) + (t * t * lab2[i]); })); 2804 return new Color_1(lab, 'lab'); 2805 }; 2806 } else if (colors.length === 4) { 2807 // cubic bezier interpolation 2808 var lab3; 2809 (assign$2 = colors.map(function (c) { return c.lab(); }), lab0 = assign$2[0], lab1 = assign$2[1], lab2 = assign$2[2], lab3 = assign$2[3]); 2810 I = function(t) { 2811 var lab = ([0, 1, 2].map(function (i) { return ((1-t)*(1-t)*(1-t) * lab0[i]) + (3 * (1-t) * (1-t) * t * lab1[i]) + (3 * (1-t) * t * t * lab2[i]) + (t*t*t * lab3[i]); })); 2812 return new Color_1(lab, 'lab'); 2813 }; 2814 } else if (colors.length === 5) { 2815 var I0 = bezier(colors.slice(0, 3)); 2816 var I1 = bezier(colors.slice(2, 5)); 2817 I = function(t) { 2818 if (t < 0.5) { 2819 return I0(t*2); 2820 } else { 2821 return I1((t-0.5)*2); 2822 } 2823 }; 2824 } 2825 return I; 2826 }; 2827 2828 var bezier_1 = function (colors) { 2829 var f = bezier(colors); 2830 f.scale = function () { return scale(f); }; 2831 return f; 2832 }; 2833 2834 /* 2835 * interpolates between a set of colors uzing a bezier spline 2836 * blend mode formulas taken from http://www.venture-ware.com/kevin/coding/lets-learn-math-photoshop-blend-modes/ 2837 */ 2838 2839 2840 2841 2842 var blend = function (bottom, top, mode) { 2843 if (!blend[mode]) { 2844 throw new Error('unknown blend mode ' + mode); 2845 } 2846 return blend[mode](bottom, top); 2847 }; 2848 2849 var blend_f = function (f) { return function (bottom,top) { 2850 var c0 = chroma_1(top).rgb(); 2851 var c1 = chroma_1(bottom).rgb(); 2852 return chroma_1.rgb(f(c0, c1)); 2853 }; }; 2854 2855 var each = function (f) { return function (c0, c1) { 2856 var out = []; 2857 out[0] = f(c0[0], c1[0]); 2858 out[1] = f(c0[1], c1[1]); 2859 out[2] = f(c0[2], c1[2]); 2860 return out; 2861 }; }; 2862 2863 var normal = function (a) { return a; }; 2864 var multiply = function (a,b) { return a * b / 255; }; 2865 var darken$1 = function (a,b) { return a > b ? b : a; }; 2866 var lighten = function (a,b) { return a > b ? a : b; }; 2867 var screen = function (a,b) { return 255 * (1 - (1-a/255) * (1-b/255)); }; 2868 var overlay = function (a,b) { return b < 128 ? 2 * a * b / 255 : 255 * (1 - 2 * (1 - a / 255 ) * ( 1 - b / 255 )); }; 2869 var burn = function (a,b) { return 255 * (1 - (1 - b / 255) / (a/255)); }; 2870 var dodge = function (a,b) { 2871 if (a === 255) { return 255; } 2872 a = 255 * (b / 255) / (1 - a / 255); 2873 return a > 255 ? 255 : a 2874 }; 2875 2876 // # add = (a,b) -> 2877 // # if (a + b > 255) then 255 else a + b 2878 2879 blend.normal = blend_f(each(normal)); 2880 blend.multiply = blend_f(each(multiply)); 2881 blend.screen = blend_f(each(screen)); 2882 blend.overlay = blend_f(each(overlay)); 2883 blend.darken = blend_f(each(darken$1)); 2884 blend.lighten = blend_f(each(lighten)); 2885 blend.dodge = blend_f(each(dodge)); 2886 blend.burn = blend_f(each(burn)); 2887 // blend.add = blend_f(each(add)); 2888 2889 var blend_1 = blend; 2890 2891 // cubehelix interpolation 2892 // based on D.A. Green "A colour scheme for the display of astronomical intensity images" 2893 // http://astron-soc.in/bulletin/11June/289392011.pdf 2894 2895 var type$k = utils.type; 2896 var clip_rgb$3 = utils.clip_rgb; 2897 var TWOPI$2 = utils.TWOPI; 2898 var pow$6 = Math.pow; 2899 var sin$2 = Math.sin; 2900 var cos$3 = Math.cos; 2901 2902 2903 var cubehelix = function(start, rotations, hue, gamma, lightness) { 2904 if ( start === void 0 ) start=300; 2905 if ( rotations === void 0 ) rotations=-1.5; 2906 if ( hue === void 0 ) hue=1; 2907 if ( gamma === void 0 ) gamma=1; 2908 if ( lightness === void 0 ) lightness=[0,1]; 2909 2910 var dh = 0, dl; 2911 if (type$k(lightness) === 'array') { 2912 dl = lightness[1] - lightness[0]; 2913 } else { 2914 dl = 0; 2915 lightness = [lightness, lightness]; 2916 } 2917 2918 var f = function(fract) { 2919 var a = TWOPI$2 * (((start+120)/360) + (rotations * fract)); 2920 var l = pow$6(lightness[0] + (dl * fract), gamma); 2921 var h = dh !== 0 ? hue[0] + (fract * dh) : hue; 2922 var amp = (h * l * (1-l)) / 2; 2923 var cos_a = cos$3(a); 2924 var sin_a = sin$2(a); 2925 var r = l + (amp * ((-0.14861 * cos_a) + (1.78277* sin_a))); 2926 var g = l + (amp * ((-0.29227 * cos_a) - (0.90649* sin_a))); 2927 var b = l + (amp * (+1.97294 * cos_a)); 2928 return chroma_1(clip_rgb$3([r*255,g*255,b*255,1])); 2929 }; 2930 2931 f.start = function(s) { 2932 if ((s == null)) { return start; } 2933 start = s; 2934 return f; 2935 }; 2936 2937 f.rotations = function(r) { 2938 if ((r == null)) { return rotations; } 2939 rotations = r; 2940 return f; 2941 }; 2942 2943 f.gamma = function(g) { 2944 if ((g == null)) { return gamma; } 2945 gamma = g; 2946 return f; 2947 }; 2948 2949 f.hue = function(h) { 2950 if ((h == null)) { return hue; } 2951 hue = h; 2952 if (type$k(hue) === 'array') { 2953 dh = hue[1] - hue[0]; 2954 if (dh === 0) { hue = hue[1]; } 2955 } else { 2956 dh = 0; 2957 } 2958 return f; 2959 }; 2960 2961 f.lightness = function(h) { 2962 if ((h == null)) { return lightness; } 2963 if (type$k(h) === 'array') { 2964 lightness = h; 2965 dl = h[1] - h[0]; 2966 } else { 2967 lightness = [h,h]; 2968 dl = 0; 2969 } 2970 return f; 2971 }; 2972 2973 f.scale = function () { return chroma_1.scale(f); }; 2974 2975 f.hue(hue); 2976 2977 return f; 2978 }; 2979 2980 var digits = '0123456789abcdef'; 2981 2982 var floor$2 = Math.floor; 2983 var random = Math.random; 2984 2985 var random_1 = function () { 2986 var code = '#'; 2987 for (var i=0; i<6; i++) { 2988 code += digits.charAt(floor$2(random() * 16)); 2989 } 2990 return new Color_1(code, 'hex'); 2991 }; 2992 2993 var log$1 = Math.log; 2994 var pow$7 = Math.pow; 2995 var floor$3 = Math.floor; 2996 var abs = Math.abs; 2997 2998 2999 var analyze = function (data, key) { 3000 if ( key === void 0 ) key=null; 3001 3002 var r = { 3003 min: Number.MAX_VALUE, 3004 max: Number.MAX_VALUE*-1, 3005 sum: 0, 3006 values: [], 3007 count: 0 3008 }; 3009 if (type(data) === 'object') { 3010 data = Object.values(data); 3011 } 3012 data.forEach(function (val) { 3013 if (key && type(val) === 'object') { val = val[key]; } 3014 if (val !== undefined && val !== null && !isNaN(val)) { 3015 r.values.push(val); 3016 r.sum += val; 3017 if (val < r.min) { r.min = val; } 3018 if (val > r.max) { r.max = val; } 3019 r.count += 1; 3020 } 3021 }); 3022 3023 r.domain = [r.min, r.max]; 3024 3025 r.limits = function (mode, num) { return limits(r, mode, num); }; 3026 3027 return r; 3028 }; 3029 3030 3031 var limits = function (data, mode, num) { 3032 if ( mode === void 0 ) mode='equal'; 3033 if ( num === void 0 ) num=7; 3034 3035 if (type(data) == 'array') { 3036 data = analyze(data); 3037 } 3038 var min = data.min; 3039 var max = data.max; 3040 var values = data.values.sort(function (a,b) { return a-b; }); 3041 3042 if (num === 1) { return [min,max]; } 3043 3044 var limits = []; 3045 3046 if (mode.substr(0,1) === 'c') { // continuous 3047 limits.push(min); 3048 limits.push(max); 3049 } 3050 3051 if (mode.substr(0,1) === 'e') { // equal interval 3052 limits.push(min); 3053 for (var i=1; i<num; i++) { 3054 limits.push(min+((i/num)*(max-min))); 3055 } 3056 limits.push(max); 3057 } 3058 3059 else if (mode.substr(0,1) === 'l') { // log scale 3060 if (min <= 0) { 3061 throw new Error('Logarithmic scales are only possible for values > 0'); 3062 } 3063 var min_log = Math.LOG10E * log$1(min); 3064 var max_log = Math.LOG10E * log$1(max); 3065 limits.push(min); 3066 for (var i$1=1; i$1<num; i$1++) { 3067 limits.push(pow$7(10, min_log + ((i$1/num) * (max_log - min_log)))); 3068 } 3069 limits.push(max); 3070 } 3071 3072 else if (mode.substr(0,1) === 'q') { // quantile scale 3073 limits.push(min); 3074 for (var i$2=1; i$2<num; i$2++) { 3075 var p = ((values.length-1) * i$2)/num; 3076 var pb = floor$3(p); 3077 if (pb === p) { 3078 limits.push(values[pb]); 3079 } else { // p > pb 3080 var pr = p - pb; 3081 limits.push((values[pb]*(1-pr)) + (values[pb+1]*pr)); 3082 } 3083 } 3084 limits.push(max); 3085 3086 } 3087 3088 else if (mode.substr(0,1) === 'k') { // k-means clustering 3089 /* 3090 implementation based on 3091 http://code.google.com/p/figue/source/browse/trunk/figue.js#336 3092 simplified for 1-d input values 3093 */ 3094 var cluster; 3095 var n = values.length; 3096 var assignments = new Array(n); 3097 var clusterSizes = new Array(num); 3098 var repeat = true; 3099 var nb_iters = 0; 3100 var centroids = null; 3101 3102 // get seed values 3103 centroids = []; 3104 centroids.push(min); 3105 for (var i$3=1; i$3<num; i$3++) { 3106 centroids.push(min + ((i$3/num) * (max-min))); 3107 } 3108 centroids.push(max); 3109 3110 while (repeat) { 3111 // assignment step 3112 for (var j=0; j<num; j++) { 3113 clusterSizes[j] = 0; 3114 } 3115 for (var i$4=0; i$4<n; i$4++) { 3116 var value = values[i$4]; 3117 var mindist = Number.MAX_VALUE; 3118 var best = (void 0); 3119 for (var j$1=0; j$1<num; j$1++) { 3120 var dist = abs(centroids[j$1]-value); 3121 if (dist < mindist) { 3122 mindist = dist; 3123 best = j$1; 3124 } 3125 clusterSizes[best]++; 3126 assignments[i$4] = best; 3127 } 3128 } 3129 3130 // update centroids step 3131 var newCentroids = new Array(num); 3132 for (var j$2=0; j$2<num; j$2++) { 3133 newCentroids[j$2] = null; 3134 } 3135 for (var i$5=0; i$5<n; i$5++) { 3136 cluster = assignments[i$5]; 3137 if (newCentroids[cluster] === null) { 3138 newCentroids[cluster] = values[i$5]; 3139 } else { 3140 newCentroids[cluster] += values[i$5]; 3141 } 3142 } 3143 for (var j$3=0; j$3<num; j$3++) { 3144 newCentroids[j$3] *= 1/clusterSizes[j$3]; 3145 } 3146 3147 // check convergence 3148 repeat = false; 3149 for (var j$4=0; j$4<num; j$4++) { 3150 if (newCentroids[j$4] !== centroids[j$4]) { 3151 repeat = true; 3152 break; 3153 } 3154 } 3155 3156 centroids = newCentroids; 3157 nb_iters++; 3158 3159 if (nb_iters > 200) { 3160 repeat = false; 3161 } 3162 } 3163 3164 // finished k-means clustering 3165 // the next part is borrowed from gabrielflor.it 3166 var kClusters = {}; 3167 for (var j$5=0; j$5<num; j$5++) { 3168 kClusters[j$5] = []; 3169 } 3170 for (var i$6=0; i$6<n; i$6++) { 3171 cluster = assignments[i$6]; 3172 kClusters[cluster].push(values[i$6]); 3173 } 3174 var tmpKMeansBreaks = []; 3175 for (var j$6=0; j$6<num; j$6++) { 3176 tmpKMeansBreaks.push(kClusters[j$6][0]); 3177 tmpKMeansBreaks.push(kClusters[j$6][kClusters[j$6].length-1]); 3178 } 3179 tmpKMeansBreaks = tmpKMeansBreaks.sort(function (a,b){ return a-b; }); 3180 limits.push(tmpKMeansBreaks[0]); 3181 for (var i$7=1; i$7 < tmpKMeansBreaks.length; i$7+= 2) { 3182 var v = tmpKMeansBreaks[i$7]; 3183 if (!isNaN(v) && (limits.indexOf(v) === -1)) { 3184 limits.push(v); 3185 } 3186 } 3187 } 3188 return limits; 3189 }; 3190 3191 var analyze_1 = {analyze: analyze, limits: limits}; 3192 3193 var contrast = function (a, b) { 3194 // WCAG contrast ratio 3195 // see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef 3196 a = new Color_1(a); 3197 b = new Color_1(b); 3198 var l1 = a.luminance(); 3199 var l2 = b.luminance(); 3200 return l1 > l2 ? (l1 + 0.05) / (l2 + 0.05) : (l2 + 0.05) / (l1 + 0.05); 3201 }; 3202 3203 var sqrt$4 = Math.sqrt; 3204 var atan2$2 = Math.atan2; 3205 var abs$1 = Math.abs; 3206 var cos$4 = Math.cos; 3207 var PI$2 = Math.PI; 3208 3209 var deltaE = function(a, b, L, C) { 3210 if ( L === void 0 ) L=1; 3211 if ( C === void 0 ) C=1; 3212 3213 // Delta E (CMC) 3214 // see http://www.brucelindbloom.com/index.html?Eqn_DeltaE_CMC.html 3215 a = new Color_1(a); 3216 b = new Color_1(b); 3217 var ref = Array.from(a.lab()); 3218 var L1 = ref[0]; 3219 var a1 = ref[1]; 3220 var b1 = ref[2]; 3221 var ref$1 = Array.from(b.lab()); 3222 var L2 = ref$1[0]; 3223 var a2 = ref$1[1]; 3224 var b2 = ref$1[2]; 3225 var c1 = sqrt$4((a1 * a1) + (b1 * b1)); 3226 var c2 = sqrt$4((a2 * a2) + (b2 * b2)); 3227 var sl = L1 < 16.0 ? 0.511 : (0.040975 * L1) / (1.0 + (0.01765 * L1)); 3228 var sc = ((0.0638 * c1) / (1.0 + (0.0131 * c1))) + 0.638; 3229 var h1 = c1 < 0.000001 ? 0.0 : (atan2$2(b1, a1) * 180.0) / PI$2; 3230 while (h1 < 0) { h1 += 360; } 3231 while (h1 >= 360) { h1 -= 360; } 3232 var t = (h1 >= 164.0) && (h1 <= 345.0) ? (0.56 + abs$1(0.2 * cos$4((PI$2 * (h1 + 168.0)) / 180.0))) : (0.36 + abs$1(0.4 * cos$4((PI$2 * (h1 + 35.0)) / 180.0))); 3233 var c4 = c1 * c1 * c1 * c1; 3234 var f = sqrt$4(c4 / (c4 + 1900.0)); 3235 var sh = sc * (((f * t) + 1.0) - f); 3236 var delL = L1 - L2; 3237 var delC = c1 - c2; 3238 var delA = a1 - a2; 3239 var delB = b1 - b2; 3240 var dH2 = ((delA * delA) + (delB * delB)) - (delC * delC); 3241 var v1 = delL / (L * sl); 3242 var v2 = delC / (C * sc); 3243 var v3 = sh; 3244 return sqrt$4((v1 * v1) + (v2 * v2) + (dH2 / (v3 * v3))); 3245 }; 3246 3247 // simple Euclidean distance 3248 var distance = function(a, b, mode) { 3249 if ( mode === void 0 ) mode='lab'; 3250 3251 // Delta E (CIE 1976) 3252 // see http://www.brucelindbloom.com/index.html?Equations.html 3253 a = new Color_1(a); 3254 b = new Color_1(b); 3255 var l1 = a.get(mode); 3256 var l2 = b.get(mode); 3257 var sum_sq = 0; 3258 for (var i in l1) { 3259 var d = (l1[i] || 0) - (l2[i] || 0); 3260 sum_sq += d*d; 3261 } 3262 return Math.sqrt(sum_sq); 3263 }; 3264 3265 var valid = function () { 3266 var args = [], len = arguments.length; 3267 while ( len-- ) args[ len ] = arguments[ len ]; 3268 3269 try { 3270 new (Function.prototype.bind.apply( Color_1, [ null ].concat( args) )); 3271 return true; 3272 } catch (e) { 3273 return false; 3274 } 3275 }; 3276 3277 // some pre-defined color scales: 3278 3279 3280 3281 3282 var scales = { 3283 cool: function cool() { return scale([chroma_1.hsl(180,1,.9), chroma_1.hsl(250,.7,.4)]) }, 3284 hot: function hot() { return scale(['#000','#f00','#ff0','#fff']).mode('rgb') } 3285 }; 3286 3287 /** 3288 ColorBrewer colors for chroma.js 3289 3290 Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The 3291 Pennsylvania State University. 3292 3293 Licensed under the Apache License, Version 2.0 (the "License"); 3294 you may not use this file except in compliance with the License. 3295 You may obtain a copy of the License at 3296 http://www.apache.org/licenses/LICENSE-2.0 3297 3298 Unless required by applicable law or agreed to in writing, software distributed 3299 under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 3300 CONDITIONS OF ANY KIND, either express or implied. See the License for the 3301 specific language governing permissions and limitations under the License. 3302 */ 3303 3304 var colorbrewer = { 3305 // sequential 3306 OrRd: ['#fff7ec', '#fee8c8', '#fdd49e', '#fdbb84', '#fc8d59', '#ef6548', '#d7301f', '#b30000', '#7f0000'], 3307 PuBu: ['#fff7fb', '#ece7f2', '#d0d1e6', '#a6bddb', '#74a9cf', '#3690c0', '#0570b0', '#045a8d', '#023858'], 3308 BuPu: ['#f7fcfd', '#e0ecf4', '#bfd3e6', '#9ebcda', '#8c96c6', '#8c6bb1', '#88419d', '#810f7c', '#4d004b'], 3309 Oranges: ['#fff5eb', '#fee6ce', '#fdd0a2', '#fdae6b', '#fd8d3c', '#f16913', '#d94801', '#a63603', '#7f2704'], 3310 BuGn: ['#f7fcfd', '#e5f5f9', '#ccece6', '#99d8c9', '#66c2a4', '#41ae76', '#238b45', '#006d2c', '#00441b'], 3311 YlOrBr: ['#ffffe5', '#fff7bc', '#fee391', '#fec44f', '#fe9929', '#ec7014', '#cc4c02', '#993404', '#662506'], 3312 YlGn: ['#ffffe5', '#f7fcb9', '#d9f0a3', '#addd8e', '#78c679', '#41ab5d', '#238443', '#006837', '#004529'], 3313 Reds: ['#fff5f0', '#fee0d2', '#fcbba1', '#fc9272', '#fb6a4a', '#ef3b2c', '#cb181d', '#a50f15', '#67000d'], 3314 RdPu: ['#fff7f3', '#fde0dd', '#fcc5c0', '#fa9fb5', '#f768a1', '#dd3497', '#ae017e', '#7a0177', '#49006a'], 3315 Greens: ['#f7fcf5', '#e5f5e0', '#c7e9c0', '#a1d99b', '#74c476', '#41ab5d', '#238b45', '#006d2c', '#00441b'], 3316 YlGnBu: ['#ffffd9', '#edf8b1', '#c7e9b4', '#7fcdbb', '#41b6c4', '#1d91c0', '#225ea8', '#253494', '#081d58'], 3317 Purples: ['#fcfbfd', '#efedf5', '#dadaeb', '#bcbddc', '#9e9ac8', '#807dba', '#6a51a3', '#54278f', '#3f007d'], 3318 GnBu: ['#f7fcf0', '#e0f3db', '#ccebc5', '#a8ddb5', '#7bccc4', '#4eb3d3', '#2b8cbe', '#0868ac', '#084081'], 3319 Greys: ['#ffffff', '#f0f0f0', '#d9d9d9', '#bdbdbd', '#969696', '#737373', '#525252', '#252525', '#000000'], 3320 YlOrRd: ['#ffffcc', '#ffeda0', '#fed976', '#feb24c', '#fd8d3c', '#fc4e2a', '#e31a1c', '#bd0026', '#800026'], 3321 PuRd: ['#f7f4f9', '#e7e1ef', '#d4b9da', '#c994c7', '#df65b0', '#e7298a', '#ce1256', '#980043', '#67001f'], 3322 Blues: ['#f7fbff', '#deebf7', '#c6dbef', '#9ecae1', '#6baed6', '#4292c6', '#2171b5', '#08519c', '#08306b'], 3323 PuBuGn: ['#fff7fb', '#ece2f0', '#d0d1e6', '#a6bddb', '#67a9cf', '#3690c0', '#02818a', '#016c59', '#014636'], 3324 Viridis: ['#440154', '#482777', '#3f4a8a', '#31678e', '#26838f', '#1f9d8a', '#6cce5a', '#b6de2b', '#fee825'], 3325 3326 // diverging 3327 3328 Spectral: ['#9e0142', '#d53e4f', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#e6f598', '#abdda4', '#66c2a5', '#3288bd', '#5e4fa2'], 3329 RdYlGn: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#d9ef8b', '#a6d96a', '#66bd63', '#1a9850', '#006837'], 3330 RdBu: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#f7f7f7', '#d1e5f0', '#92c5de', '#4393c3', '#2166ac', '#053061'], 3331 PiYG: ['#8e0152', '#c51b7d', '#de77ae', '#f1b6da', '#fde0ef', '#f7f7f7', '#e6f5d0', '#b8e186', '#7fbc41', '#4d9221', '#276419'], 3332 PRGn: ['#40004b', '#762a83', '#9970ab', '#c2a5cf', '#e7d4e8', '#f7f7f7', '#d9f0d3', '#a6dba0', '#5aae61', '#1b7837', '#00441b'], 3333 RdYlBu: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee090', '#ffffbf', '#e0f3f8', '#abd9e9', '#74add1', '#4575b4', '#313695'], 3334 BrBG: ['#543005', '#8c510a', '#bf812d', '#dfc27d', '#f6e8c3', '#f5f5f5', '#c7eae5', '#80cdc1', '#35978f', '#01665e', '#003c30'], 3335 RdGy: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#ffffff', '#e0e0e0', '#bababa', '#878787', '#4d4d4d', '#1a1a1a'], 3336 PuOr: ['#7f3b08', '#b35806', '#e08214', '#fdb863', '#fee0b6', '#f7f7f7', '#d8daeb', '#b2abd2', '#8073ac', '#542788', '#2d004b'], 3337 3338 // qualitative 3339 3340 Set2: ['#66c2a5', '#fc8d62', '#8da0cb', '#e78ac3', '#a6d854', '#ffd92f', '#e5c494', '#b3b3b3'], 3341 Accent: ['#7fc97f', '#beaed4', '#fdc086', '#ffff99', '#386cb0', '#f0027f', '#bf5b17', '#666666'], 3342 Set1: ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00', '#ffff33', '#a65628', '#f781bf', '#999999'], 3343 Set3: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd', '#ccebc5', '#ffed6f'], 3344 Dark2: ['#1b9e77', '#d95f02', '#7570b3', '#e7298a', '#66a61e', '#e6ab02', '#a6761d', '#666666'], 3345 Paired: ['#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99', '#e31a1c', '#fdbf6f', '#ff7f00', '#cab2d6', '#6a3d9a', '#ffff99', '#b15928'], 3346 Pastel2: ['#b3e2cd', '#fdcdac', '#cbd5e8', '#f4cae4', '#e6f5c9', '#fff2ae', '#f1e2cc', '#cccccc'], 3347 Pastel1: ['#fbb4ae', '#b3cde3', '#ccebc5', '#decbe4', '#fed9a6', '#ffffcc', '#e5d8bd', '#fddaec', '#f2f2f2'], 3348 }; 3349 3350 // add lowercase aliases for case-insensitive matches 3351 for (var i$1 = 0, list$1 = Object.keys(colorbrewer); i$1 < list$1.length; i$1 += 1) { 3352 var key = list$1[i$1]; 3353 3354 colorbrewer[key.toLowerCase()] = colorbrewer[key]; 3355 } 3356 3357 var colorbrewer_1 = colorbrewer; 3358 3359 // feel free to comment out anything to rollup 3360 // a smaller chroma.js built 3361 3362 // io --> convert colors 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 // operators --> modify existing Colors 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 // interpolators 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 // generators -- > create new colors 3401 chroma_1.average = average; 3402 chroma_1.bezier = bezier_1; 3403 chroma_1.blend = blend_1; 3404 chroma_1.cubehelix = cubehelix; 3405 chroma_1.mix = chroma_1.interpolate = mix; 3406 chroma_1.random = random_1; 3407 chroma_1.scale = scale; 3408 3409 // other utility methods 3410 chroma_1.analyze = analyze_1.analyze; 3411 chroma_1.contrast = contrast; 3412 chroma_1.deltaE = deltaE; 3413 chroma_1.distance = distance; 3414 chroma_1.limits = analyze_1.limits; 3415 chroma_1.valid = valid; 3416 3417 // scale 3418 chroma_1.scales = scales; 3419 3420 // colors 3421 chroma_1.colors = w3cx11_1; 3422 chroma_1.brewer = colorbrewer_1; 3423 3424 var chroma_js = chroma_1; 3425 3426 return chroma_js; 3427 3428 }))); 3429 }); 3430 3431 function generateColorVariables(key, format, colorStr, opacity, altFormats = []) { 3432 const parsedColor = chroma(colorStr); 3433 const alts = altFormats.reduce((a, alt) => { 3434 a.push(...generateColorVariables(alt.id, alt.format, colorStr, opacity)); 3435 return a; 3436 }, []); 3437 switch (format) { 3438 case 'hex': 3439 return [{ key, value: colorStr }, ...alts]; 3440 case 'hsl': 3441 return [ 3442 { 3443 key, 3444 value: parsedColor.css('hsl'), 3445 }, 3446 ...alts, 3447 ]; 3448 case 'hsl-values': { 3449 const hsl = parsedColor.hsl(); 3450 const alpha = opacity ? `,${parsedColor.alpha()}` : ''; 3451 const h = isNaN(hsl[0]) ? 0 : hsl[0]; 3452 return [ 3453 { 3454 key, 3455 value: `${h},${hsl[1] * 100}%,${hsl[2] * 100}%${alpha}`, 3456 }, 3457 ...alts, 3458 ]; 3459 } 3460 case 'hsl-split': { 3461 const hsl = parsedColor.hsl(); 3462 const h = isNaN(hsl[0]) ? 0 : hsl[0]; 3463 const out = [ 3464 { 3465 key: `${key}-h`, 3466 value: h.toString(), 3467 }, 3468 { 3469 key: `${key}-s`, 3470 value: (hsl[1] * 100).toString() + '%', 3471 }, 3472 { 3473 key: `${key}-l`, 3474 value: (hsl[2] * 100).toString() + '%', 3475 }, 3476 ...alts, 3477 ]; 3478 if (opacity) 3479 out.push({ 3480 key: `${key}-a`, 3481 value: parsedColor.alpha().toString(), 3482 }); 3483 return out; 3484 } 3485 case 'hsl-split-decimal': { 3486 const hsl = parsedColor.hsl(); 3487 const h = isNaN(hsl[0]) ? 0 : hsl[0]; 3488 const out = [ 3489 { 3490 key: `${key}-h`, 3491 value: h.toString(), 3492 }, 3493 { 3494 key: `${key}-s`, 3495 value: hsl[1].toString(), 3496 }, 3497 { 3498 key: `${key}-l`, 3499 value: hsl[2].toString(), 3500 }, 3501 ...alts, 3502 ]; 3503 if (opacity) 3504 out.push({ 3505 key: `${key}-a`, 3506 value: parsedColor.alpha().toString(), 3507 }); 3508 return out; 3509 } 3510 case 'rgb': 3511 return [ 3512 { 3513 key, 3514 value: parsedColor.css(), 3515 }, 3516 ...alts, 3517 ]; 3518 case 'rgb-values': { 3519 const rgb = parsedColor.rgb(); 3520 const alpha = opacity ? `,${parsedColor.alpha()}` : ''; 3521 return [ 3522 { 3523 key, 3524 value: `${rgb[0]},${rgb[1]},${rgb[2]}${alpha}`, 3525 }, 3526 ...alts, 3527 ]; 3528 } 3529 case 'rgb-split': { 3530 const rgb = parsedColor.rgb(); 3531 const out = [ 3532 { 3533 key: `${key}-r`, 3534 value: rgb[0].toString(), 3535 }, 3536 { 3537 key: `${key}-g`, 3538 value: rgb[1].toString(), 3539 }, 3540 { 3541 key: `${key}-b`, 3542 value: rgb[2].toString(), 3543 }, 3544 ...alts, 3545 ]; 3546 if (opacity) 3547 out.push({ 3548 key: `${key}-a`, 3549 value: parsedColor.alpha().toString(), 3550 }); 3551 return out; 3552 } 3553 } 3554 } 3555 function pushColors(arr, id, from, to, format, step, pad) { 3556 const scale = chroma.scale([from.trim(), to.trim()]).domain([0, 100]); 3557 for (let i = 0; i <= 100; i++) { 3558 if (i % step === 0) { 3559 const c = scale(i); 3560 arr.push(...generateColorVariables(`${id}-${i.toString().padStart(pad, '0')}`, format, c.css(), c.alpha() !== 1)); 3561 } 3562 } 3563 } 3564 function getCSSVariables(settings, config, gradients, settingsManager) { 3565 const vars = []; 3566 const themedLight = []; 3567 const themedDark = []; 3568 const gradientCandidates = {}; 3569 const gradientCandidatesLight = {}; 3570 const gradientCandidatesDark = {}; 3571 const seenGradientSections = new Set(); 3572 for (const key in settings) { 3573 const [sectionId, settingId, modifier] = key.split('@@'); 3574 const section = config[sectionId]; 3575 if (!section) 3576 continue; 3577 const setting = config[sectionId][settingId]; 3578 if (!setting) 3579 continue; 3580 const value = settings[key]; 3581 switch (setting.type) { 3582 case SettingType.VARIABLE_NUMBER: 3583 case SettingType.VARIABLE_NUMBER_SLIDER: { 3584 const format = setting 3585 .format; 3586 const val = value !== undefined 3587 ? value 3588 : setting.default; 3589 vars.push({ 3590 key: setting.id, 3591 value: `${val}${format || ''}`, 3592 }); 3593 continue; 3594 } 3595 case SettingType.VARIABLE_TEXT: 3596 case SettingType.VARIABLE_SELECT: { 3597 const format_text = setting; 3598 let text = value !== undefined 3599 ? value.toString() 3600 : format_text.default.toString(); 3601 if (format_text.quotes) { 3602 if (text !== `""`) { 3603 text = `'${text}'`; 3604 } 3605 else { 3606 text = ``; 3607 } 3608 } 3609 vars.push({ 3610 key: setting.id, 3611 value: text, 3612 }); 3613 continue; 3614 } 3615 case SettingType.VARIABLE_COLOR: { 3616 if (!seenGradientSections.has(sectionId)) 3617 seenGradientSections.add(sectionId); 3618 const colorSetting = setting; 3619 const color = value !== undefined ? value.toString() : colorSetting.default; 3620 vars.push(...generateColorVariables(setting.id, colorSetting.format, color, colorSetting.opacity, colorSetting['alt-format'])); 3621 generateColorVariables(setting.id, 'rgb', color, colorSetting.opacity).forEach((kv) => { 3622 gradientCandidates[kv.key] = kv.value; 3623 }); 3624 continue; 3625 } 3626 case SettingType.VARIABLE_THEMED_COLOR: { 3627 if (!seenGradientSections.has(sectionId)) 3628 seenGradientSections.add(sectionId); 3629 const colorSetting = setting; 3630 const colorKey = modifier === 'light' ? 'default-light' : 'default-dark'; 3631 const color = value !== undefined ? value.toString() : colorSetting[colorKey]; 3632 (modifier === 'light' ? themedLight : themedDark).push(...generateColorVariables(setting.id, colorSetting.format, color, colorSetting.opacity, colorSetting['alt-format'])); 3633 generateColorVariables(setting.id, 'rgb', color, colorSetting.opacity).forEach((kv) => { 3634 if (modifier === 'light') { 3635 gradientCandidatesLight[kv.key] = kv.value; 3636 } 3637 else { 3638 gradientCandidatesDark[kv.key] = kv.value; 3639 } 3640 }); 3641 continue; 3642 } 3643 } 3644 } 3645 seenGradientSections.forEach((sectionId) => { 3646 const g = gradients[sectionId]; 3647 if (!g) 3648 return; 3649 g.forEach((def) => { 3650 var _a, _b, _c; 3651 const { from, to, format, step, id, pad = 0 } = def; 3652 if (gradientCandidatesLight[from]) { 3653 const fromColor = gradientCandidatesLight[from]; 3654 const toColor = gradientCandidatesLight[to] || 3655 ((_a = settingsManager.plugin.getCSSVar(to).light) === null || _a === void 0 ? void 0 : _a.trim()); 3656 if (toColor) { 3657 pushColors(themedLight, id, fromColor, toColor, format, step, pad); 3658 } 3659 } 3660 if (gradientCandidatesDark[from]) { 3661 const fromColor = gradientCandidatesDark[from]; 3662 const toColor = gradientCandidatesDark[to] || 3663 ((_b = settingsManager.plugin.getCSSVar(to).dark) === null || _b === void 0 ? void 0 : _b.trim()); 3664 if (toColor) { 3665 pushColors(themedDark, id, fromColor, toColor, format, step, pad); 3666 } 3667 } 3668 if (gradientCandidates[from]) { 3669 const fromColor = gradientCandidates[from]; 3670 const toColor = gradientCandidates[to] || 3671 ((_c = settingsManager.plugin.getCSSVar(to).current) === null || _c === void 0 ? void 0 : _c.trim()); 3672 if (toColor) { 3673 pushColors(vars, id, fromColor, toColor, format, step, pad); 3674 } 3675 } 3676 }); 3677 }); 3678 return [vars, themedLight, themedDark]; 3679 } 3680 class CSSSettingsManager { 3681 constructor(plugin) { 3682 this.config = {}; 3683 this.gradients = {}; 3684 this.plugin = plugin; 3685 this.settings = {}; 3686 this.styleTag = document.createElement('style'); 3687 this.styleTag.id = 'css-settings-manager'; 3688 document.getElementsByTagName('head')[0].appendChild(this.styleTag); 3689 } 3690 cleanup() { 3691 this.styleTag.remove(); 3692 this.removeClasses(); 3693 } 3694 save() { 3695 return __awaiter(this, void 0, void 0, function* () { 3696 yield this.plugin.saveData(this.settings); 3697 this.setCSSVariables(); 3698 }); 3699 } 3700 load() { 3701 return __awaiter(this, void 0, void 0, function* () { 3702 this.settings = Object.assign({}, yield this.plugin.loadData()); 3703 }); 3704 } 3705 initClasses() { 3706 Object.keys(this.config).forEach((section) => { 3707 const config = this.config[section]; 3708 Object.keys(config).forEach((settingId) => { 3709 const setting = config[settingId]; 3710 if (setting.type === SettingType.CLASS_TOGGLE) { 3711 const classToggle = setting; 3712 const value = this.getSetting(section, settingId); 3713 if (value === true || 3714 (value === undefined && classToggle.default === true)) { 3715 document.body.classList.add(setting.id); 3716 } 3717 } 3718 else if (setting.type === SettingType.CLASS_SELECT) { 3719 const multiToggle = setting; 3720 let value = this.getSetting(section, settingId); 3721 if (value === undefined && !!multiToggle.default) { 3722 value = multiToggle.default; 3723 } 3724 else if (value === undefined) { 3725 value = 'none'; 3726 } 3727 if (value !== 'none') { 3728 document.body.classList.add(value); 3729 } 3730 } 3731 }); 3732 }); 3733 } 3734 removeClasses() { 3735 Object.keys(this.config).forEach((section) => { 3736 const config = this.config[section]; 3737 Object.keys(config).forEach((settingId) => { 3738 const setting = config[settingId]; 3739 if (setting.type === SettingType.CLASS_TOGGLE) { 3740 document.body.classList.remove(setting.id); 3741 } 3742 else if (setting.type === SettingType.CLASS_SELECT) { 3743 const multiToggle = setting; 3744 multiToggle.options.forEach((v) => { 3745 if (typeof v === 'string') { 3746 document.body.classList.remove(v); 3747 } 3748 else { 3749 document.body.classList.remove(v.value); 3750 } 3751 }); 3752 } 3753 }); 3754 }); 3755 } 3756 setCSSVariables() { 3757 const [vars, themedLight, themedDark] = getCSSVariables(this.settings, this.config, this.gradients, this); 3758 this.styleTag.innerText = ` 3759 body.css-settings-manager { 3760 ${vars.reduce((combined, current) => { 3761 return combined + `--${current.key}: ${current.value}; `; 3762 }, '')} 3763 } 3764 3765 body.theme-light.css-settings-manager { 3766 ${themedLight.reduce((combined, current) => { 3767 return combined + `--${current.key}: ${current.value}; `; 3768 }, '')} 3769 } 3770 3771 body.theme-dark.css-settings-manager { 3772 ${themedDark.reduce((combined, current) => { 3773 return combined + `--${current.key}: ${current.value}; `; 3774 }, '')} 3775 } 3776 ` 3777 .trim() 3778 .replace(/[\r\n\s]+/g, ' '); 3779 this.plugin.app.workspace.trigger('css-change', { 3780 source: 'style-settings', 3781 }); 3782 } 3783 setConfig(settings) { 3784 this.config = {}; 3785 this.gradients = {}; 3786 settings.forEach((s) => { 3787 this.config[s.id] = {}; 3788 s.settings.forEach((setting) => { 3789 this.config[s.id][setting.id] = setting; 3790 if (setting.type === SettingType.COLOR_GRADIENT) { 3791 if (!this.gradients[s.id]) 3792 this.gradients[s.id] = []; 3793 this.gradients[s.id].push(setting); 3794 } 3795 }); 3796 }); 3797 let pruned = false; 3798 for (const key in this.settings) { 3799 const [sectionId, settingId] = key.split('@@'); 3800 if (this.config[sectionId] && !this.config[sectionId][settingId]) { 3801 delete this.settings[key]; 3802 pruned = true; 3803 } 3804 } 3805 if (pruned) { 3806 this.save(); 3807 } 3808 else { 3809 this.setCSSVariables(); 3810 } 3811 } 3812 getSetting(sectionId, settingId) { 3813 return this.settings[`${sectionId}@@${settingId}`]; 3814 } 3815 getSettings(sectionId, ids) { 3816 return ids.reduce((settings, id) => { 3817 const fullId = `${sectionId}@@${id}`; 3818 const alts = ['dark', 'light']; 3819 if (this.settings[fullId]) { 3820 settings[fullId] = this.settings[fullId]; 3821 } 3822 alts.forEach((alt) => { 3823 const id = `${fullId}@@${alt}`; 3824 if (this.settings[id]) { 3825 settings[id] = this.settings[id]; 3826 } 3827 }); 3828 return settings; 3829 }, {}); 3830 } 3831 setSetting(sectionId, settingId, value) { 3832 this.settings[`${sectionId}@@${settingId}`] = value; 3833 this.save(); 3834 this.removeClasses(); 3835 this.initClasses(); 3836 } 3837 setSettings(settings) { 3838 Object.keys(settings).forEach((id) => { 3839 this.settings[id] = settings[id]; 3840 }); 3841 this.removeClasses(); 3842 this.initClasses(); 3843 return this.save(); 3844 } 3845 clearSetting(sectionId, settingId) { 3846 delete this.settings[`${sectionId}@@${settingId}`]; 3847 this.save(); 3848 this.removeClasses(); 3849 this.initClasses(); 3850 } 3851 clearSection(sectionId) { 3852 Object.keys(this.settings).forEach((key) => { 3853 const [section] = key.split('@@'); 3854 if (section === sectionId) { 3855 delete this.settings[key]; 3856 } 3857 }); 3858 this.save(); 3859 this.removeClasses(); 3860 this.initClasses(); 3861 } 3862 export(section, config) { 3863 new ExportModal(this.plugin.app, this.plugin, section, config).open(); 3864 } 3865 import() { 3866 new ImportModal(this.plugin.app, this.plugin).open(); 3867 } 3868 } 3869 3870 const ar = {}; 3871 3872 const cz = {}; 3873 3874 const da = {}; 3875 3876 const de = { 3877 'Default:': 'Standard:', 3878 'Error:': 'Fehler:', 3879 'missing default light value, or value is not in a valid color format': 'Fehlender heller standard Wert oder Wert ist in keinem validen Farb-Format', 3880 'missing default dark value, or value is not in a valid color format': 'Fehlender dunkler standard Wert oder Wert ist in keinem validen Farb-Format', 3881 'missing default value, or value is not in a valid color format': 'Fehlender standard Wert oder Wert ist in keinem validen Farb-Format', 3882 'missing default value': 'Fehlender standard Wert', 3883 }; 3884 3885 const en = { 3886 'Default:': 'Default:', 3887 'Error:': 'Error:', 3888 'missing default light value, or value is not in a valid color format': 'missing default light value, or value is not in a valid color format', 3889 'missing default dark value, or value is not in a valid color format': 'missing default dark value, or value is not in a valid color format', 3890 'missing default value, or value is not in a valid color format': 'missing default value, or value is not in a valid color format', 3891 'missing default value': 'missing default value', 3892 }; 3893 3894 const es = {}; 3895 3896 const fr = {}; 3897 3898 const hi = {}; 3899 3900 const id = {}; 3901 3902 const it = {}; 3903 3904 const ja = {}; 3905 3906 const ko = {}; 3907 3908 const nl = { 3909 'Default:': 'Standaard:', 3910 'Error:': 'Error:', 3911 'missing default light value, or value is not in a valid color format': 'Geen standaard waarde voor het lichte thema, of de waarde is niet in het goede formaat', 3912 'missing default dark value, or value is not in a valid color format': 'Geen standaard waarde voor het donkere thema, of de waarde is niet in het goede formaat', 3913 'missing default value, or value is not in a valid color format': 'Geen standaard waarde, of de waarde is niet in het goede formaat', 3914 'missing default value': 'Geen standaard waarde', 3915 }; 3916 3917 const no = {}; 3918 3919 const pl = {}; 3920 3921 const pt = {}; 3922 3923 const ptBr = {}; 3924 3925 const ro = {}; 3926 3927 const ru = {}; 3928 3929 const sq = {}; 3930 3931 const tr = {}; 3932 3933 const uk = {}; 3934 3935 const zh = { 3936 'Default:': '默认:', 3937 'Error:': '错误:', 3938 'missing default light value, or value is not in a valid color format': '缺少默认的浅色模式色值,或该色值没有采用一个有效的颜色格式', 3939 'missing default dark value, or value is not in a valid color format': '缺少默认的深色模式色值,或该色值没有采用一个有效的颜色格式', 3940 'missing default value, or value is not in a valid color format': '缺少默认色值,或该色值没有采用一个有效的颜色格式', 3941 'missing default value': '缺少默认色值', 3942 }; 3943 3944 const zhTw = {}; 3945 3946 const lang = window.localStorage.getItem('language'); 3947 const localeMap = { 3948 ar, 3949 cz, 3950 da, 3951 de, 3952 en, 3953 es, 3954 fr, 3955 hi, 3956 id, 3957 it, 3958 ja, 3959 ko, 3960 nl, 3961 no, 3962 pl, 3963 'pt-BR': ptBr, 3964 pt, 3965 ro, 3966 ru, 3967 sq, 3968 tr, 3969 uk, 3970 'zh-TW': zhTw, 3971 zh, 3972 }; 3973 const locale = localeMap[lang || 'en']; 3974 function t(str) { 3975 if (!locale) { 3976 console.error('Error: Style Settings locale not found', lang); 3977 } 3978 return (locale && locale[str]) || en[str]; 3979 } 3980 3981 const settingRegExp = /\/\*!?\s*@settings[\r\n]+?([\s\S]+?)\*\//g; 3982 const nameRegExp = /^name:\s*(.+)$/m; 3983 function getTitle(config) { 3984 if (lang) { 3985 return config[`title.${lang}`] || config.title; 3986 } 3987 return config.title; 3988 } 3989 function getDescription(config) { 3990 if (lang) { 3991 return (config[`description.${lang}`] || 3992 config.description); 3993 } 3994 return config.description; 3995 } 3996 function isValidDefaultColor(color) { 3997 return /^(#|rgb|hsl)/.test(color); 3998 } 3999 function getPickrSettings(opts) { 4000 const { el, isView, containerEl, swatches, opacity, defaultColor } = opts; 4001 return { 4002 el, 4003 container: isView ? document.body : containerEl, 4004 theme: 'nano', 4005 swatches, 4006 lockOpacity: !opacity, 4007 default: defaultColor, 4008 position: 'left-middle', 4009 components: { 4010 preview: true, 4011 hue: true, 4012 opacity: !!opacity, 4013 interaction: { 4014 hex: true, 4015 rgba: true, 4016 hsla: true, 4017 input: true, 4018 cancel: true, 4019 save: true, 4020 }, 4021 }, 4022 }; 4023 } 4024 function onPickrCancel(instance) { 4025 instance.hide(); 4026 } 4027 function sanitizeText(str) { 4028 if (str === '') { 4029 return `""`; 4030 } 4031 return str.replace(/[;<>]/g, ''); 4032 } 4033 function createDescription(description, def, defLabel) { 4034 const fragment = createFragment(); 4035 if (description) { 4036 fragment.appendChild(document.createTextNode(description)); 4037 } 4038 if (def) { 4039 const small = createEl('small'); 4040 small.appendChild(createEl('strong', { text: `${t('Default:')} ` })); 4041 small.appendChild(document.createTextNode(defLabel || def)); 4042 const div = createEl('div'); 4043 div.appendChild(small); 4044 fragment.appendChild(div); 4045 } 4046 return fragment; 4047 } 4048 4049 var fuzzysort = createCommonjsModule(function (module) { 4050 ((root, UMD) => { 4051 if(module.exports) module.exports = UMD(); 4052 else root['fuzzysort'] = UMD(); 4053 })(commonjsGlobal, _ => { 4054 4055 var single = (search, target) => { if(search=='farzher')return {target:"farzher was here (^-^*)/",score:0,_indexes:[0]} 4056 if(!search || !target) return NULL 4057 4058 var preparedSearch = getPreparedSearch(search); 4059 if(!isObj(target)) target = getPrepared(target); 4060 4061 var searchBitflags = preparedSearch.bitflags; 4062 if((searchBitflags & target._bitflags) !== searchBitflags) return NULL 4063 4064 return algorithm(preparedSearch, target) 4065 }; 4066 4067 4068 var go = (search, targets, options) => { if(search=='farzher')return [{target:"farzher was here (^-^*)/",score:0,_indexes:[0],obj:targets?targets[0]:NULL}] 4069 if(!search) return options&&options.all ? all(search, targets, options) : noResults 4070 4071 var preparedSearch = getPreparedSearch(search); 4072 var searchBitflags = preparedSearch.bitflags; 4073 preparedSearch.containsSpace; 4074 4075 var threshold = options&&options.threshold || INT_MIN; 4076 var limit = options&&options['limit'] || INT_MAX; // for some reason only limit breaks when minified 4077 4078 var resultsLen = 0; var limitedCount = 0; 4079 var targetsLen = targets.length; 4080 4081 // This code is copy/pasted 3 times for performance reasons [options.keys, options.key, no keys] 4082 4083 // options.key 4084 if(options && options.key) { 4085 var key = options.key; 4086 for(var i = 0; i < targetsLen; ++i) { var obj = targets[i]; 4087 var target = getValue(obj, key); 4088 if(!target) continue 4089 if(!isObj(target)) target = getPrepared(target); 4090 4091 if((searchBitflags & target._bitflags) !== searchBitflags) continue 4092 var result = algorithm(preparedSearch, target); 4093 if(result === NULL) continue 4094 if(result.score < threshold) continue 4095 4096 // have to clone result so duplicate targets from different obj can each reference the correct obj 4097 result = {target:result.target, _targetLower:'', _targetLowerCodes:NULL, _nextBeginningIndexes:NULL, _bitflags:0, score:result.score, _indexes:result._indexes, obj:obj}; // hidden 4098 4099 if(resultsLen < limit) { q.add(result); ++resultsLen; } 4100 else { 4101 ++limitedCount; 4102 if(result.score > q.peek().score) q.replaceTop(result); 4103 } 4104 } 4105 4106 // options.keys 4107 } else if(options && options.keys) { 4108 var scoreFn = options['scoreFn'] || defaultScoreFn; 4109 var keys = options.keys; 4110 var keysLen = keys.length; 4111 for(var i = 0; i < targetsLen; ++i) { var obj = targets[i]; 4112 var objResults = new Array(keysLen); 4113 for (var keyI = 0; keyI < keysLen; ++keyI) { 4114 var key = keys[keyI]; 4115 var target = getValue(obj, key); 4116 if(!target) { objResults[keyI] = NULL; continue } 4117 if(!isObj(target)) target = getPrepared(target); 4118 4119 if((searchBitflags & target._bitflags) !== searchBitflags) objResults[keyI] = NULL; 4120 else objResults[keyI] = algorithm(preparedSearch, target); 4121 } 4122 objResults.obj = obj; // before scoreFn so scoreFn can use it 4123 var score = scoreFn(objResults); 4124 if(score === NULL) continue 4125 if(score < threshold) continue 4126 objResults.score = score; 4127 if(resultsLen < limit) { q.add(objResults); ++resultsLen; } 4128 else { 4129 ++limitedCount; 4130 if(score > q.peek().score) q.replaceTop(objResults); 4131 } 4132 } 4133 4134 // no keys 4135 } else { 4136 for(var i = 0; i < targetsLen; ++i) { var target = targets[i]; 4137 if(!target) continue 4138 if(!isObj(target)) target = getPrepared(target); 4139 4140 if((searchBitflags & target._bitflags) !== searchBitflags) continue 4141 var result = algorithm(preparedSearch, target); 4142 if(result === NULL) continue 4143 if(result.score < threshold) continue 4144 if(resultsLen < limit) { q.add(result); ++resultsLen; } 4145 else { 4146 ++limitedCount; 4147 if(result.score > q.peek().score) q.replaceTop(result); 4148 } 4149 } 4150 } 4151 4152 if(resultsLen === 0) return noResults 4153 var results = new Array(resultsLen); 4154 for(var i = resultsLen - 1; i >= 0; --i) results[i] = q.poll(); 4155 results.total = resultsLen + limitedCount; 4156 return results 4157 }; 4158 4159 4160 var highlight = (result, hOpen, hClose) => { 4161 if(typeof hOpen === 'function') return highlightCallback(result, hOpen) 4162 if(result === NULL) return NULL 4163 if(hOpen === undefined) hOpen = '<b>'; 4164 if(hClose === undefined) hClose = '</b>'; 4165 var highlighted = ''; 4166 var matchesIndex = 0; 4167 var opened = false; 4168 var target = result.target; 4169 var targetLen = target.length; 4170 var indexes = result._indexes; 4171 indexes = indexes.slice(0, indexes.len).sort((a,b)=>a-b); 4172 for(var i = 0; i < targetLen; ++i) { var char = target[i]; 4173 if(indexes[matchesIndex] === i) { 4174 ++matchesIndex; 4175 if(!opened) { opened = true; 4176 highlighted += hOpen; 4177 } 4178 4179 if(matchesIndex === indexes.length) { 4180 highlighted += char + hClose + target.substr(i+1); 4181 break 4182 } 4183 } else { 4184 if(opened) { opened = false; 4185 highlighted += hClose; 4186 } 4187 } 4188 highlighted += char; 4189 } 4190 4191 return highlighted 4192 }; 4193 var highlightCallback = (result, cb) => { 4194 if(result === NULL) return NULL 4195 var target = result.target; 4196 var targetLen = target.length; 4197 var indexes = result._indexes; 4198 indexes = indexes.slice(0, indexes.len).sort((a,b)=>a-b); 4199 var highlighted = ''; 4200 var matchI = 0; 4201 var indexesI = 0; 4202 var opened = false; 4203 var result = []; 4204 for(var i = 0; i < targetLen; ++i) { var char = target[i]; 4205 if(indexes[indexesI] === i) { 4206 ++indexesI; 4207 if(!opened) { opened = true; 4208 result.push(highlighted); highlighted = ''; 4209 } 4210 4211 if(indexesI === indexes.length) { 4212 highlighted += char; 4213 result.push(cb(highlighted, matchI++)); highlighted = ''; 4214 result.push(target.substr(i+1)); 4215 break 4216 } 4217 } else { 4218 if(opened) { opened = false; 4219 result.push(cb(highlighted, matchI++)); highlighted = ''; 4220 } 4221 } 4222 highlighted += char; 4223 } 4224 return result 4225 }; 4226 4227 4228 var indexes = result => result._indexes.slice(0, result._indexes.len).sort((a,b)=>a-b); 4229 4230 4231 var prepare = (target) => { 4232 if(typeof target !== 'string') target = ''; 4233 var info = prepareLowerInfo(target); 4234 return {'target':target, _targetLower:info._lower, _targetLowerCodes:info.lowerCodes, _nextBeginningIndexes:NULL, _bitflags:info.bitflags, 'score':NULL, _indexes:[0], 'obj':NULL} // hidden 4235 }; 4236 4237 4238 // Below this point is only internal code 4239 // Below this point is only internal code 4240 // Below this point is only internal code 4241 // Below this point is only internal code 4242 4243 4244 var prepareSearch = (search) => { 4245 if(typeof search !== 'string') search = ''; 4246 search = search.trim(); 4247 var info = prepareLowerInfo(search); 4248 4249 var spaceSearches = []; 4250 if(info.containsSpace) { 4251 var searches = search.split(/\s+/); 4252 searches = [...new Set(searches)]; // distinct 4253 for(var i=0; i<searches.length; i++) { 4254 if(searches[i] === '') continue 4255 var _info = prepareLowerInfo(searches[i]); 4256 spaceSearches.push({lowerCodes:_info.lowerCodes, _lower:searches[i].toLowerCase(), containsSpace:false}); 4257 } 4258 } 4259 4260 return {lowerCodes: info.lowerCodes, bitflags: info.bitflags, containsSpace: info.containsSpace, _lower: info._lower, spaceSearches: spaceSearches} 4261 }; 4262 4263 4264 4265 var getPrepared = (target) => { 4266 if(target.length > 999) return prepare(target) // don't cache huge targets 4267 var targetPrepared = preparedCache.get(target); 4268 if(targetPrepared !== undefined) return targetPrepared 4269 targetPrepared = prepare(target); 4270 preparedCache.set(target, targetPrepared); 4271 return targetPrepared 4272 }; 4273 var getPreparedSearch = (search) => { 4274 if(search.length > 999) return prepareSearch(search) // don't cache huge searches 4275 var searchPrepared = preparedSearchCache.get(search); 4276 if(searchPrepared !== undefined) return searchPrepared 4277 searchPrepared = prepareSearch(search); 4278 preparedSearchCache.set(search, searchPrepared); 4279 return searchPrepared 4280 }; 4281 4282 4283 var all = (search, targets, options) => { 4284 var results = []; results.total = targets.length; 4285 4286 var limit = options && options.limit || INT_MAX; 4287 4288 if(options && options.key) { 4289 for(var i=0;i<targets.length;i++) { var obj = targets[i]; 4290 var target = getValue(obj, options.key); 4291 if(!target) continue 4292 if(!isObj(target)) target = getPrepared(target); 4293 target.score = INT_MIN; 4294 target._indexes.len = 0; 4295 var result = target; 4296 result = {target:result.target, _targetLower:'', _targetLowerCodes:NULL, _nextBeginningIndexes:NULL, _bitflags:0, score:target.score, _indexes:NULL, obj:obj}; // hidden 4297 results.push(result); if(results.length >= limit) return results 4298 } 4299 } else if(options && options.keys) { 4300 for(var i=0;i<targets.length;i++) { var obj = targets[i]; 4301 var objResults = new Array(options.keys.length); 4302 for (var keyI = options.keys.length - 1; keyI >= 0; --keyI) { 4303 var target = getValue(obj, options.keys[keyI]); 4304 if(!target) { objResults[keyI] = NULL; continue } 4305 if(!isObj(target)) target = getPrepared(target); 4306 target.score = INT_MIN; 4307 target._indexes.len = 0; 4308 objResults[keyI] = target; 4309 } 4310 objResults.obj = obj; 4311 objResults.score = INT_MIN; 4312 results.push(objResults); if(results.length >= limit) return results 4313 } 4314 } else { 4315 for(var i=0;i<targets.length;i++) { var target = targets[i]; 4316 if(!target) continue 4317 if(!isObj(target)) target = getPrepared(target); 4318 target.score = INT_MIN; 4319 target._indexes.len = 0; 4320 results.push(target); if(results.length >= limit) return results 4321 } 4322 } 4323 4324 return results 4325 }; 4326 4327 4328 var algorithm = (preparedSearch, prepared, allowSpaces=false) => { 4329 if(allowSpaces===false && preparedSearch.containsSpace) return algorithmSpaces(preparedSearch, prepared) 4330 4331 var searchLower = preparedSearch._lower; 4332 var searchLowerCodes = preparedSearch.lowerCodes; 4333 var searchLowerCode = searchLowerCodes[0]; 4334 var targetLowerCodes = prepared._targetLowerCodes; 4335 var searchLen = searchLowerCodes.length; 4336 var targetLen = targetLowerCodes.length; 4337 var searchI = 0; // where we at 4338 var targetI = 0; // where you at 4339 var matchesSimpleLen = 0; 4340 4341 // very basic fuzzy match; to remove non-matching targets ASAP! 4342 // walk through target. find sequential matches. 4343 // if all chars aren't found then exit 4344 for(;;) { 4345 var isMatch = searchLowerCode === targetLowerCodes[targetI]; 4346 if(isMatch) { 4347 matchesSimple[matchesSimpleLen++] = targetI; 4348 ++searchI; if(searchI === searchLen) break 4349 searchLowerCode = searchLowerCodes[searchI]; 4350 } 4351 ++targetI; if(targetI >= targetLen) return NULL // Failed to find searchI 4352 } 4353 4354 var searchI = 0; 4355 var successStrict = false; 4356 var matchesStrictLen = 0; 4357 4358 var nextBeginningIndexes = prepared._nextBeginningIndexes; 4359 if(nextBeginningIndexes === NULL) nextBeginningIndexes = prepared._nextBeginningIndexes = prepareNextBeginningIndexes(prepared.target); 4360 targetI = matchesSimple[0]===0 ? 0 : nextBeginningIndexes[matchesSimple[0]-1]; 4361 4362 // Our target string successfully matched all characters in sequence! 4363 // Let's try a more advanced and strict test to improve the score 4364 // only count it as a match if it's consecutive or a beginning character! 4365 var backtrackCount = 0; 4366 if(targetI !== targetLen) for(;;) { 4367 if(targetI >= targetLen) { 4368 // We failed to find a good spot for this search char, go back to the previous search char and force it forward 4369 if(searchI <= 0) break // We failed to push chars forward for a better match 4370 4371 ++backtrackCount; if(backtrackCount > 200) break // exponential backtracking is taking too long, just give up and return a bad match 4372 4373 --searchI; 4374 var lastMatch = matchesStrict[--matchesStrictLen]; 4375 targetI = nextBeginningIndexes[lastMatch]; 4376 4377 } else { 4378 var isMatch = searchLowerCodes[searchI] === targetLowerCodes[targetI]; 4379 if(isMatch) { 4380 matchesStrict[matchesStrictLen++] = targetI; 4381 ++searchI; if(searchI === searchLen) { successStrict = true; break } 4382 ++targetI; 4383 } else { 4384 targetI = nextBeginningIndexes[targetI]; 4385 } 4386 } 4387 } 4388 4389 // check if it's a substring match 4390 var substringIndex = prepared._targetLower.indexOf(searchLower, matchesSimple[0]); // perf: this is slow 4391 var isSubstring = ~substringIndex; 4392 if(isSubstring && !successStrict) { // rewrite the indexes from basic to the substring 4393 for(var i=0; i<matchesSimpleLen; ++i) matchesSimple[i] = substringIndex+i; 4394 } 4395 var isSubstringBeginning = false; 4396 if(isSubstring) { 4397 isSubstringBeginning = prepared._nextBeginningIndexes[substringIndex-1] === substringIndex; 4398 } 4399 4400 { // tally up the score & keep track of matches for highlighting later 4401 if(successStrict) { var matchesBest = matchesStrict; var matchesBestLen = matchesStrictLen; } 4402 else { var matchesBest = matchesSimple; var matchesBestLen = matchesSimpleLen; } 4403 4404 var score = 0; 4405 4406 var extraMatchGroupCount = 0; 4407 for(var i = 1; i < searchLen; ++i) { 4408 if(matchesBest[i] - matchesBest[i-1] !== 1) {score -= matchesBest[i]; ++extraMatchGroupCount;} 4409 } 4410 var unmatchedDistance = matchesBest[searchLen-1] - matchesBest[0] - (searchLen-1); 4411 4412 score -= (12+unmatchedDistance) * extraMatchGroupCount; // penality for more groups 4413 4414 if(matchesBest[0] !== 0) score -= matchesBest[0]*matchesBest[0]*.2; // penality for not starting near the beginning 4415 4416 if(!successStrict) { 4417 score *= 1000; 4418 } else { 4419 // successStrict on a target with too many beginning indexes loses points for being a bad target 4420 var uniqueBeginningIndexes = 1; 4421 for(var i = nextBeginningIndexes[0]; i < targetLen; i=nextBeginningIndexes[i]) ++uniqueBeginningIndexes; 4422 4423 if(uniqueBeginningIndexes > 24) score *= (uniqueBeginningIndexes-24)*10; // quite arbitrary numbers here ... 4424 } 4425 4426 if(isSubstring) score /= 1+searchLen*searchLen*1; // bonus for being a full substring 4427 if(isSubstringBeginning) score /= 1+searchLen*searchLen*1; // bonus for substring starting on a beginningIndex 4428 4429 score -= targetLen - searchLen; // penality for longer targets 4430 prepared.score = score; 4431 4432 for(var i = 0; i < matchesBestLen; ++i) prepared._indexes[i] = matchesBest[i]; 4433 prepared._indexes.len = matchesBestLen; 4434 4435 return prepared 4436 } 4437 }; 4438 var algorithmSpaces = (preparedSearch, target) => { 4439 var seen_indexes = new Set(); 4440 var score = 0; 4441 var result = NULL; 4442 4443 var first_seen_index_last_search = 0; 4444 var searches = preparedSearch.spaceSearches; 4445 for(var i=0; i<searches.length; ++i) { 4446 var search = searches[i]; 4447 4448 result = algorithm(search, target); 4449 if(result === NULL) return NULL 4450 4451 score += result.score; 4452 4453 // dock points based on order otherwise "c man" returns Manifest.cpp instead of CheatManager.h 4454 if(result._indexes[0] < first_seen_index_last_search) { 4455 score -= first_seen_index_last_search - result._indexes[0]; 4456 } 4457 first_seen_index_last_search = result._indexes[0]; 4458 4459 for(var j=0; j<result._indexes.len; ++j) seen_indexes.add(result._indexes[j]); 4460 } 4461 4462 // allows a search with spaces that's an exact substring to score well 4463 var allowSpacesResult = algorithm(preparedSearch, target, /*allowSpaces=*/true); 4464 if(allowSpacesResult !== NULL && allowSpacesResult.score > score) { 4465 return allowSpacesResult 4466 } 4467 4468 result.score = score; 4469 4470 var i = 0; 4471 for (let index of seen_indexes) result._indexes[i++] = index; 4472 result._indexes.len = i; 4473 4474 return result 4475 }; 4476 4477 4478 var prepareLowerInfo = (str) => { 4479 var strLen = str.length; 4480 var lower = str.toLowerCase(); 4481 var lowerCodes = []; // new Array(strLen) sparse array is too slow 4482 var bitflags = 0; 4483 var containsSpace = false; // space isn't stored in bitflags because of how searching with a space works 4484 4485 for(var i = 0; i < strLen; ++i) { 4486 var lowerCode = lowerCodes[i] = lower.charCodeAt(i); 4487 4488 if(lowerCode === 32) { 4489 containsSpace = true; 4490 continue // it's important that we don't set any bitflags for space 4491 } 4492 4493 var bit = lowerCode>=97&&lowerCode<=122 ? lowerCode-97 // alphabet 4494 : lowerCode>=48&&lowerCode<=57 ? 26 // numbers 4495 // 3 bits available 4496 : lowerCode<=127 ? 30 // other ascii 4497 : 31; // other utf8 4498 bitflags |= 1<<bit; 4499 } 4500 4501 return {lowerCodes:lowerCodes, bitflags:bitflags, containsSpace:containsSpace, _lower:lower} 4502 }; 4503 var prepareBeginningIndexes = (target) => { 4504 var targetLen = target.length; 4505 var beginningIndexes = []; var beginningIndexesLen = 0; 4506 var wasUpper = false; 4507 var wasAlphanum = false; 4508 for(var i = 0; i < targetLen; ++i) { 4509 var targetCode = target.charCodeAt(i); 4510 var isUpper = targetCode>=65&&targetCode<=90; 4511 var isAlphanum = isUpper || targetCode>=97&&targetCode<=122 || targetCode>=48&&targetCode<=57; 4512 var isBeginning = isUpper && !wasUpper || !wasAlphanum || !isAlphanum; 4513 wasUpper = isUpper; 4514 wasAlphanum = isAlphanum; 4515 if(isBeginning) beginningIndexes[beginningIndexesLen++] = i; 4516 } 4517 return beginningIndexes 4518 }; 4519 var prepareNextBeginningIndexes = (target) => { 4520 var targetLen = target.length; 4521 var beginningIndexes = prepareBeginningIndexes(target); 4522 var nextBeginningIndexes = []; // new Array(targetLen) sparse array is too slow 4523 var lastIsBeginning = beginningIndexes[0]; 4524 var lastIsBeginningI = 0; 4525 for(var i = 0; i < targetLen; ++i) { 4526 if(lastIsBeginning > i) { 4527 nextBeginningIndexes[i] = lastIsBeginning; 4528 } else { 4529 lastIsBeginning = beginningIndexes[++lastIsBeginningI]; 4530 nextBeginningIndexes[i] = lastIsBeginning===undefined ? targetLen : lastIsBeginning; 4531 } 4532 } 4533 return nextBeginningIndexes 4534 }; 4535 4536 4537 var cleanup = () => { preparedCache.clear(); preparedSearchCache.clear(); matchesSimple = []; matchesStrict = []; }; 4538 4539 var preparedCache = new Map(); 4540 var preparedSearchCache = new Map(); 4541 var matchesSimple = []; var matchesStrict = []; 4542 4543 4544 // for use with keys. just returns the maximum score 4545 var defaultScoreFn = (a) => { 4546 var max = INT_MIN; 4547 var len = a.length; 4548 for (var i = 0; i < len; ++i) { 4549 var result = a[i]; if(result === NULL) continue 4550 var score = result.score; 4551 if(score > max) max = score; 4552 } 4553 if(max === INT_MIN) return NULL 4554 return max 4555 }; 4556 4557 // prop = 'key' 2.5ms optimized for this case, seems to be about as fast as direct obj[prop] 4558 // prop = 'key1.key2' 10ms 4559 // prop = ['key1', 'key2'] 27ms 4560 var getValue = (obj, prop) => { 4561 var tmp = obj[prop]; if(tmp !== undefined) return tmp 4562 var segs = prop; 4563 if(!Array.isArray(prop)) segs = prop.split('.'); 4564 var len = segs.length; 4565 var i = -1; 4566 while (obj && (++i < len)) obj = obj[segs[i]]; 4567 return obj 4568 }; 4569 4570 var isObj = (x) => { return typeof x === 'object' }; // faster as a function 4571 // var INT_MAX = 9007199254740991; var INT_MIN = -INT_MAX 4572 var INT_MAX = Infinity; var INT_MIN = -INT_MAX; 4573 var noResults = []; noResults.total = 0; 4574 var NULL = null; 4575 4576 4577 // Hacked version of https://github.com/lemire/FastPriorityQueue.js 4578 var fastpriorityqueue=r=>{var e=[],o=0,a={},v=r=>{for(var a=0,v=e[a],c=1;c<o;){var s=c+1;a=c,s<o&&e[s].score<e[c].score&&(a=s),e[a-1>>1]=e[a],c=1+(a<<1);}for(var f=a-1>>1;a>0&&v.score<e[f].score;f=(a=f)-1>>1)e[a]=e[f];e[a]=v;};return a.add=(r=>{var a=o;e[o++]=r;for(var v=a-1>>1;a>0&&r.score<e[v].score;v=(a=v)-1>>1)e[a]=e[v];e[a]=r;}),a.poll=(r=>{if(0!==o){var a=e[0];return e[0]=e[--o],v(),a}}),a.peek=(r=>{if(0!==o)return e[0]}),a.replaceTop=(r=>{e[0]=r,v();}),a}; 4579 var q = fastpriorityqueue(); // reuse this 4580 4581 4582 // fuzzysort is written this way for minification. all names are mangeled unless quoted 4583 return {'single':single, 'go':go, 'highlight':highlight, 'prepare':prepare, 'indexes':indexes, 'cleanup':cleanup} 4584 }); // UMD 4585 4586 // TODO: (feature) frecency 4587 // TODO: (perf) use different sorting algo depending on the # of results? 4588 // TODO: (perf) preparedCache is a memory leak 4589 // TODO: (like sublime) backslash === forwardslash 4590 // TODO: (perf) prepareSearch seems slow 4591 }); 4592 4593 class AbstractSettingComponent extends obsidian.Component { 4594 constructor(parent, sectionId, sectionName, setting, settingsManager, isView) { 4595 super(); 4596 this.childEl = null; 4597 this.parent = parent; 4598 this.sectionId = sectionId; 4599 this.sectionName = sectionName; 4600 this.setting = setting; 4601 this.settingsManager = settingsManager; 4602 this.isView = isView; 4603 } 4604 get containerEl() { 4605 return this.parent instanceof HTMLElement 4606 ? this.parent 4607 : this.parent.childEl; 4608 } 4609 onload() { 4610 this.render(); 4611 } 4612 onunload() { 4613 this.destroy(); 4614 } 4615 /** 4616 * Matches the Component against `str`. A perfect match returns 0, no match returns negative infinity. 4617 * 4618 * @param str the string to match this Component against. 4619 */ 4620 match(str) { 4621 var _a, _b, _c, _d; 4622 if (!str) { 4623 return Number.NEGATIVE_INFINITY; 4624 } 4625 return Math.max((_b = (_a = fuzzysort.single(str, getTitle(this.setting))) === null || _a === void 0 ? void 0 : _a.score) !== null && _b !== void 0 ? _b : Number.NEGATIVE_INFINITY, (_d = (_c = fuzzysort.single(str, getDescription(this.setting))) === null || _c === void 0 ? void 0 : _c.score) !== null && _d !== void 0 ? _d : Number.NEGATIVE_INFINITY); 4626 } 4627 /** 4628 * Matches the Component against `str`. A match returns true, no match or a bad match returns false. 4629 * 4630 * @param str the string to match this Component against. 4631 */ 4632 decisiveMatch(str) { 4633 return this.match(str) > -100000; 4634 } 4635 } 4636 4637 const resetTooltip = 'Restore default'; 4638 4639 class ClassMultiToggleSettingComponent extends AbstractSettingComponent { 4640 render() { 4641 const title = getTitle(this.setting); 4642 const description = getDescription(this.setting); 4643 if (typeof this.setting.default !== 'string') { 4644 return console.error(`${t('Error:')} ${title} ${t('missing default value')}`); 4645 } 4646 let prevValue = this.getPreviousValue(); 4647 const defaultLabel = this.getDefaultOptionLabel(); 4648 this.settingEl = new obsidian.Setting(this.containerEl); 4649 this.settingEl.setName(title); 4650 this.settingEl.setDesc(createDescription(description, this.setting.default, defaultLabel)); 4651 this.settingEl.addDropdown((dropdown) => { 4652 if (this.setting.allowEmpty) { 4653 dropdown.addOption('none', ''); 4654 } 4655 for (const o of this.setting.options) { 4656 if (typeof o === 'string') { 4657 dropdown.addOption(o, o); 4658 } 4659 else { 4660 dropdown.addOption(o.value, o.label); 4661 } 4662 } 4663 dropdown.setValue(prevValue); 4664 dropdown.onChange((value) => { 4665 this.settingsManager.setSetting(this.sectionId, this.setting.id, value); 4666 prevValue = value; 4667 }); 4668 this.dropdownComponent = dropdown; 4669 }); 4670 this.settingEl.addExtraButton((b) => { 4671 b.setIcon('reset'); 4672 b.onClick(() => { 4673 this.dropdownComponent.setValue(this.setting.default || 'none'); 4674 this.settingsManager.clearSetting(this.sectionId, this.setting.id); 4675 }); 4676 b.setTooltip(resetTooltip); 4677 }); 4678 this.settingEl.settingEl.dataset.id = this.setting.id; 4679 } 4680 destroy() { 4681 var _a; 4682 (_a = this.settingEl) === null || _a === void 0 ? void 0 : _a.settingEl.remove(); 4683 } 4684 getDefaultOption() { 4685 if (this.setting.default) { 4686 return this.setting.options.find((o) => { 4687 if (typeof o === 'string') { 4688 return o === this.setting.default; 4689 } 4690 return o.value === this.setting.default; 4691 }); 4692 } 4693 return undefined; 4694 } 4695 getDefaultOptionLabel() { 4696 const defaultOption = this.getDefaultOption(); 4697 if (defaultOption) { 4698 if (typeof defaultOption === 'string') { 4699 return defaultOption; 4700 } 4701 return defaultOption.label; 4702 } 4703 return undefined; 4704 } 4705 getPreviousValue() { 4706 const prevValue = this.settingsManager.getSetting(this.sectionId, this.setting.id); 4707 if (prevValue === undefined) { 4708 if (this.setting.default) { 4709 return this.setting.default; 4710 } 4711 return 'none'; 4712 } 4713 return prevValue; 4714 } 4715 } 4716 4717 class ClassToggleSettingComponent extends AbstractSettingComponent { 4718 render() { 4719 const title = getTitle(this.setting); 4720 const description = getDescription(this.setting); 4721 this.settingEl = new obsidian.Setting(this.containerEl); 4722 this.settingEl.setName(title); 4723 this.settingEl.setDesc(description !== null && description !== void 0 ? description : ''); 4724 this.settingEl.addToggle((toggle) => { 4725 const value = this.settingsManager.getSetting(this.sectionId, this.setting.id); 4726 toggle.setValue(value !== undefined ? !!value : !!this.setting.default); 4727 toggle.onChange((value) => { 4728 this.settingsManager.setSetting(this.sectionId, this.setting.id, value); 4729 }); 4730 this.toggleComponent = toggle; 4731 }); 4732 this.settingEl.addExtraButton((b) => { 4733 b.setIcon('reset'); 4734 b.onClick(() => { 4735 const value = !!this.setting.default; 4736 this.toggleComponent.setValue(value); 4737 this.settingsManager.clearSetting(this.sectionId, this.setting.id); 4738 }); 4739 b.setTooltip(resetTooltip); 4740 }); 4741 this.settingEl.settingEl.dataset.id = this.setting.id; 4742 } 4743 destroy() { 4744 var _a; 4745 (_a = this.settingEl) === null || _a === void 0 ? void 0 : _a.settingEl.remove(); 4746 } 4747 } 4748 4749 class InfoTextSettingComponent extends AbstractSettingComponent { 4750 render() { 4751 const title = getTitle(this.setting); 4752 const description = getDescription(this.setting); 4753 this.settingEl = new obsidian.Setting(this.containerEl); 4754 this.settingEl.setClass('style-settings-info-text'); 4755 if (title) { 4756 this.settingEl.setName(title); 4757 } 4758 if (description) { 4759 if (this.setting.markdown) { 4760 obsidian.MarkdownRenderer.renderMarkdown(description, this.settingEl.descEl, '', this); 4761 this.settingEl.descEl.addClass('style-settings-markdown'); 4762 } 4763 else { 4764 this.settingEl.setDesc(description); 4765 } 4766 } 4767 this.settingEl.settingEl.dataset.id = this.setting.id; 4768 } 4769 destroy() { 4770 var _a; 4771 (_a = this.settingEl) === null || _a === void 0 ? void 0 : _a.settingEl.remove(); 4772 } 4773 } 4774 4775 var pickr_min = createCommonjsModule(function (module, exports) { 4776 /*! Pickr 1.8.4 MIT | https://github.com/Simonwep/pickr */ 4777 !function(t,e){module.exports=e();}(self,(function(){return (()=>{var t={d:(e,o)=>{for(var n in o)t.o(o,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:o[n]});},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0});}},e={};t.d(e,{default:()=>x});var o={};function n(t,e,o,n){let i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{};e instanceof HTMLCollection||e instanceof NodeList?e=Array.from(e):Array.isArray(e)||(e=[e]),Array.isArray(o)||(o=[o]);for(const s of e)for(const e of o)s[t](e,n,{capture:!1,...i});return Array.prototype.slice.call(arguments,1)}t.r(o),t.d(o,{adjustableInputNumbers:()=>p,createElementFromString:()=>r,createFromTemplate:()=>a,eventPath:()=>l,off:()=>s,on:()=>i,resolveElement:()=>c});const i=n.bind(null,"addEventListener"),s=n.bind(null,"removeEventListener");function r(t){const e=document.createElement("div");return e.innerHTML=t.trim(),e.firstElementChild}function a(t){const e=(t,e)=>{const o=t.getAttribute(e);return t.removeAttribute(e),o},o=function(t){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const i=e(t,":obj"),s=e(t,":ref"),r=i?n[i]={}:n;s&&(n[s]=t);for(const n of Array.from(t.children)){const t=e(n,":arr"),i=o(n,t?{}:r);t&&(r[t]||(r[t]=[])).push(Object.keys(i).length?i:n);}return n};return o(r(t))}function l(t){let e=t.path||t.composedPath&&t.composedPath();if(e)return e;let o=t.target.parentElement;for(e=[t.target,o];o=o.parentElement;)e.push(o);return e.push(document,window),e}function c(t){return t instanceof Element?t:"string"==typeof t?t.split(/>>/g).reduce(((t,e,o,n)=>(t=t.querySelector(e),o<n.length-1?t.shadowRoot:t)),document):null}function p(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t=>t;function o(o){const n=[.001,.01,.1][Number(o.shiftKey||2*o.ctrlKey)]*(o.deltaY<0?1:-1);let i=0,s=t.selectionStart;t.value=t.value.replace(/[\d.]+/g,((t,o)=>o<=s&&o+t.length>=s?(s=o,e(Number(t),n,i)):(i++,t))),t.focus(),t.setSelectionRange(s,s),o.preventDefault(),t.dispatchEvent(new Event("input"));}i(t,"focus",(()=>i(window,"wheel",o,{passive:!1}))),i(t,"blur",(()=>s(window,"wheel",o)));}const{min:h,max:u,floor:d,round:v}=Math;function m(t,e,o){e/=100,o/=100;const n=d(t=t/360*6),i=t-n,s=o*(1-e),r=o*(1-i*e),a=o*(1-(1-i)*e),l=n%6;return [255*[o,r,s,s,a,o][l],255*[a,o,o,r,s,s][l],255*[s,s,a,o,o,r][l]]}function f(t,e,o){return m(t,e,o).map((t=>v(t).toString(16).padStart(2,"0")))}function g(t,e,o){const n=m(t,e,o),i=n[0]/255,s=n[1]/255,r=n[2]/255,a=h(1-i,1-s,1-r);return [100*(1===a?0:(1-i-a)/(1-a)),100*(1===a?0:(1-s-a)/(1-a)),100*(1===a?0:(1-r-a)/(1-a)),100*a]}function b(t,e,o){const n=(2-(e/=100))*(o/=100)/2;return 0!==n&&(e=1===n?0:n<.5?e*o/(2*n):e*o/(2-2*n)),[t,100*e,100*n]}function y(t,e,o){const n=h(t/=255,e/=255,o/=255),i=u(t,e,o),s=i-n;let r,a;if(0===s)r=a=0;else {a=s/i;const n=((i-t)/6+s/2)/s,l=((i-e)/6+s/2)/s,c=((i-o)/6+s/2)/s;t===i?r=c-l:e===i?r=1/3+n-c:o===i&&(r=2/3+l-n),r<0?r+=1:r>1&&(r-=1);}return [360*r,100*a,100*i]}function _(t,e,o,n){e/=100,o/=100;return [...y(255*(1-h(1,(t/=100)*(1-(n/=100))+n)),255*(1-h(1,e*(1-n)+n)),255*(1-h(1,o*(1-n)+n)))]}function w(t,e,o){e/=100;const n=2*(e*=(o/=100)<.5?o:1-o)/(o+e)*100,i=100*(o+e);return [t,isNaN(n)?0:n,i]}function A(t){return y(...t.match(/.{2}/g).map((t=>parseInt(t,16))))}function C(t){t=t.match(/^[a-zA-Z]+$/)?function(t){if("black"===t.toLowerCase())return "#000";const e=document.createElement("canvas").getContext("2d");return e.fillStyle=t,"#000"===e.fillStyle?null:e.fillStyle}(t):t;const e={cmyk:/^cmyk[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)/i,rgba:/^((rgba)|rgb)[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)[\D]*?([\d.]+|$)/i,hsla:/^((hsla)|hsl)[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)[\D]*?([\d.]+|$)/i,hsva:/^((hsva)|hsv)[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)[\D]*?([\d.]+|$)/i,hexa:/^#?(([\dA-Fa-f]{3,4})|([\dA-Fa-f]{6})|([\dA-Fa-f]{8}))$/i},o=t=>t.map((t=>/^(|\d+)\.\d+|\d+$/.test(t)?Number(t):void 0));let n;t:for(const i in e){if(!(n=e[i].exec(t)))continue;const s=t=>!!n[2]==("number"==typeof t);switch(i){case"cmyk":{const[,t,e,s,r]=o(n);if(t>100||e>100||s>100||r>100)break t;return {values:_(t,e,s,r),type:i}}case"rgba":{const[,,,t,e,r,a]=o(n);if(t>255||e>255||r>255||a<0||a>1||!s(a))break t;return {values:[...y(t,e,r),a],a,type:i}}case"hexa":{let[,t]=n;4!==t.length&&3!==t.length||(t=t.split("").map((t=>t+t)).join(""));const e=t.substring(0,6);let o=t.substring(6);return o=o?parseInt(o,16)/255:void 0,{values:[...A(e),o],a:o,type:i}}case"hsla":{const[,,,t,e,r,a]=o(n);if(t>360||e>100||r>100||a<0||a>1||!s(a))break t;return {values:[...w(t,e,r),a],a,type:i}}case"hsva":{const[,,,t,e,r,a]=o(n);if(t>360||e>100||r>100||a<0||a>1||!s(a))break t;return {values:[t,e,r,a],a,type:i}}}}return {values:null,type:null}}function $(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:1;const i=(t,e)=>function(){let o=arguments.length>0&&void 0!==arguments[0]?arguments[0]:-1;return e(~o?t.map((t=>Number(t.toFixed(o)))):t)},s={h:t,s:e,v:o,a:n,toHSVA(){const t=[s.h,s.s,s.v,s.a];return t.toString=i(t,(t=>`hsva(${t[0]}, ${t[1]}%, ${t[2]}%, ${s.a})`)),t},toHSLA(){const t=[...b(s.h,s.s,s.v),s.a];return t.toString=i(t,(t=>`hsla(${t[0]}, ${t[1]}%, ${t[2]}%, ${s.a})`)),t},toRGBA(){const t=[...m(s.h,s.s,s.v),s.a];return t.toString=i(t,(t=>`rgba(${t[0]}, ${t[1]}, ${t[2]}, ${s.a})`)),t},toCMYK(){const t=g(s.h,s.s,s.v);return t.toString=i(t,(t=>`cmyk(${t[0]}%, ${t[1]}%, ${t[2]}%, ${t[3]}%)`)),t},toHEXA(){const t=f(s.h,s.s,s.v),e=s.a>=1?"":Number((255*s.a).toFixed(0)).toString(16).toUpperCase().padStart(2,"0");return e&&t.push(e),t.toString=()=>`#${t.join("").toUpperCase()}`,t},clone:()=>$(s.h,s.s,s.v,s.a)};return s}const k=t=>Math.max(Math.min(t,1),0);function S(t){const e={options:Object.assign({lock:null,onchange:()=>0,onstop:()=>0},t),_keyboard(t){const{options:o}=e,{type:n,key:i}=t;if(document.activeElement===o.wrapper){const{lock:o}=e.options,s="ArrowUp"===i,r="ArrowRight"===i,a="ArrowDown"===i,l="ArrowLeft"===i;if("keydown"===n&&(s||r||a||l)){let n=0,i=0;"v"===o?n=s||r?1:-1:"h"===o?n=s||r?-1:1:(i=s?-1:a?1:0,n=l?-1:r?1:0),e.update(k(e.cache.x+.01*n),k(e.cache.y+.01*i)),t.preventDefault();}else i.startsWith("Arrow")&&(e.options.onstop(),t.preventDefault());}},_tapstart(t){i(document,["mouseup","touchend","touchcancel"],e._tapstop),i(document,["mousemove","touchmove"],e._tapmove),t.cancelable&&t.preventDefault(),e._tapmove(t);},_tapmove(t){const{options:o,cache:n}=e,{lock:i,element:s,wrapper:r}=o,a=r.getBoundingClientRect();let l=0,c=0;if(t){const e=t&&t.touches&&t.touches[0];l=t?(e||t).clientX:0,c=t?(e||t).clientY:0,l<a.left?l=a.left:l>a.left+a.width&&(l=a.left+a.width),c<a.top?c=a.top:c>a.top+a.height&&(c=a.top+a.height),l-=a.left,c-=a.top;}else n&&(l=n.x*a.width,c=n.y*a.height);"h"!==i&&(s.style.left=`calc(${l/a.width*100}% - ${s.offsetWidth/2}px)`),"v"!==i&&(s.style.top=`calc(${c/a.height*100}% - ${s.offsetHeight/2}px)`),e.cache={x:l/a.width,y:c/a.height};const p=k(l/a.width),h=k(c/a.height);switch(i){case"v":return o.onchange(p);case"h":return o.onchange(h);default:return o.onchange(p,h)}},_tapstop(){e.options.onstop(),s(document,["mouseup","touchend","touchcancel"],e._tapstop),s(document,["mousemove","touchmove"],e._tapmove);},trigger(){e._tapmove();},update(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;const{left:n,top:i,width:s,height:r}=e.options.wrapper.getBoundingClientRect();"h"===e.options.lock&&(o=t),e._tapmove({clientX:n+s*t,clientY:i+r*o});},destroy(){const{options:t,_tapstart:o,_keyboard:n}=e;s(document,["keydown","keyup"],n),s([t.wrapper,t.element],"mousedown",o),s([t.wrapper,t.element],"touchstart",o,{passive:!1});}},{options:o,_tapstart:n,_keyboard:r}=e;return i([o.wrapper,o.element],"mousedown",n),i([o.wrapper,o.element],"touchstart",n,{passive:!1}),i(document,["keydown","keyup"],r),e}function O(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};t=Object.assign({onchange:()=>0,className:"",elements:[]},t);const e=i(t.elements,"click",(e=>{t.elements.forEach((o=>o.classList[e.target===o?"add":"remove"](t.className))),t.onchange(e),e.stopPropagation();}));return {destroy:()=>s(...e)}}const E={variantFlipOrder:{start:"sme",middle:"mse",end:"ems"},positionFlipOrder:{top:"tbrl",right:"rltb",bottom:"btrl",left:"lrbt"},position:"bottom",margin:8},L=(t,e,o)=>{const{container:n,margin:i,position:s,variantFlipOrder:r,positionFlipOrder:a}={container:document.documentElement.getBoundingClientRect(),...E,...o},{left:l,top:c}=e.style;e.style.left="0",e.style.top="0";const p=t.getBoundingClientRect(),h=e.getBoundingClientRect(),u={t:p.top-h.height-i,b:p.bottom+i,r:p.right+i,l:p.left-h.width-i},d={vs:p.left,vm:p.left+p.width/2+-h.width/2,ve:p.left+p.width-h.width,hs:p.top,hm:p.bottom-p.height/2-h.height/2,he:p.bottom-h.height},[v,m="middle"]=s.split("-"),f=a[v],g=r[m],{top:b,left:y,bottom:_,right:w}=n;for(const t of f){const o="t"===t||"b"===t,n=u[t],[i,s]=o?["top","left"]:["left","top"],[r,a]=o?[h.height,h.width]:[h.width,h.height],[l,c]=o?[_,w]:[w,_],[p,v]=o?[b,y]:[y,b];if(!(n<p||n+r>l))for(const r of g){const l=d[(o?"v":"h")+r];if(!(l<v||l+a>c))return e.style[s]=l-h[s]+"px",e.style[i]=n-h[i]+"px",t+r}}return e.style.left=l,e.style.top=c,null};function P(t,e,o){return e in t?Object.defineProperty(t,e,{value:o,enumerable:!0,configurable:!0,writable:!0}):t[e]=o,t}class x{constructor(t){P(this,"_initializingActive",!0),P(this,"_recalc",!0),P(this,"_nanopop",null),P(this,"_root",null),P(this,"_color",$()),P(this,"_lastColor",$()),P(this,"_swatchColors",[]),P(this,"_setupAnimationFrame",null),P(this,"_eventListener",{init:[],save:[],hide:[],show:[],clear:[],change:[],changestop:[],cancel:[],swatchselect:[]}),this.options=t=Object.assign({...x.DEFAULT_OPTIONS},t);const{swatches:e,components:o,theme:n,sliders:i,lockOpacity:s,padding:r}=t;["nano","monolith"].includes(n)&&!i&&(t.sliders="h"),o.interaction||(o.interaction={});const{preview:a,opacity:l,hue:c,palette:p}=o;o.opacity=!s&&l,o.palette=p||a||l||c,this._preBuild(),this._buildComponents(),this._bindEvents(),this._finalBuild(),e&&e.length&&e.forEach((t=>this.addSwatch(t)));const{button:h,app:u}=this._root;this._nanopop=((t,e,o)=>{const n="object"!=typeof t||t instanceof HTMLElement?{reference:t,popper:e,...o}:t;return {update(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:n;const{reference:e,popper:o}=Object.assign(n,t);if(!o||!e)throw new Error("Popper- or reference-element missing.");return L(e,o,n)}}})(h,u,{margin:r}),h.setAttribute("role","button"),h.setAttribute("aria-label",this._t("btn:toggle"));const d=this;this._setupAnimationFrame=requestAnimationFrame((function e(){if(!u.offsetWidth)return d._setupAnimationFrame=requestAnimationFrame(e);d.setColor(t.default),d._rePositioningPicker(),t.defaultRepresentation&&(d._representation=t.defaultRepresentation,d.setColorRepresentation(d._representation)),t.showAlways&&d.show(),d._initializingActive=!1,d._emit("init");}));}_preBuild(){const{options:t}=this;for(const e of ["el","container"])t[e]=c(t[e]);this._root=(t=>{const{components:e,useAsButton:o,inline:n,appClass:i,theme:s,lockOpacity:r}=t.options,l=t=>t?"":'style="display:none" hidden',c=e=>t._t(e),p=a(`\n <div :ref="root" class="pickr">\n\n ${o?"":'<button type="button" :ref="button" class="pcr-button"></button>'}\n\n <div :ref="app" class="pcr-app ${i||""}" data-theme="${s}" ${n?'style="position: unset"':""} aria-label="${c("ui:dialog")}" role="window">\n <div class="pcr-selection" ${l(e.palette)}>\n <div :obj="preview" class="pcr-color-preview" ${l(e.preview)}>\n <button type="button" :ref="lastColor" class="pcr-last-color" aria-label="${c("btn:last-color")}"></button>\n <div :ref="currentColor" class="pcr-current-color"></div>\n </div>\n\n <div :obj="palette" class="pcr-color-palette">\n <div :ref="picker" class="pcr-picker"></div>\n <div :ref="palette" class="pcr-palette" tabindex="0" aria-label="${c("aria:palette")}" role="listbox"></div>\n </div>\n\n <div :obj="hue" class="pcr-color-chooser" ${l(e.hue)}>\n <div :ref="picker" class="pcr-picker"></div>\n <div :ref="slider" class="pcr-hue pcr-slider" tabindex="0" aria-label="${c("aria:hue")}" role="slider"></div>\n </div>\n\n <div :obj="opacity" class="pcr-color-opacity" ${l(e.opacity)}>\n <div :ref="picker" class="pcr-picker"></div>\n <div :ref="slider" class="pcr-opacity pcr-slider" tabindex="0" aria-label="${c("aria:opacity")}" role="slider"></div>\n </div>\n </div>\n\n <div class="pcr-swatches ${e.palette?"":"pcr-last"}" :ref="swatches"></div>\n\n <div :obj="interaction" class="pcr-interaction" ${l(Object.keys(e.interaction).length)}>\n <input :ref="result" class="pcr-result" type="text" spellcheck="false" ${l(e.interaction.input)} aria-label="${c("aria:input")}">\n\n <input :arr="options" class="pcr-type" data-type="HEXA" value="${r?"HEX":"HEXA"}" type="button" ${l(e.interaction.hex)}>\n <input :arr="options" class="pcr-type" data-type="RGBA" value="${r?"RGB":"RGBA"}" type="button" ${l(e.interaction.rgba)}>\n <input :arr="options" class="pcr-type" data-type="HSLA" value="${r?"HSL":"HSLA"}" type="button" ${l(e.interaction.hsla)}>\n <input :arr="options" class="pcr-type" data-type="HSVA" value="${r?"HSV":"HSVA"}" type="button" ${l(e.interaction.hsva)}>\n <input :arr="options" class="pcr-type" data-type="CMYK" value="CMYK" type="button" ${l(e.interaction.cmyk)}>\n\n <input :ref="save" class="pcr-save" value="${c("btn:save")}" type="button" ${l(e.interaction.save)} aria-label="${c("aria:btn:save")}">\n <input :ref="cancel" class="pcr-cancel" value="${c("btn:cancel")}" type="button" ${l(e.interaction.cancel)} aria-label="${c("aria:btn:cancel")}">\n <input :ref="clear" class="pcr-clear" value="${c("btn:clear")}" type="button" ${l(e.interaction.clear)} aria-label="${c("aria:btn:clear")}">\n </div>\n </div>\n </div>\n `),h=p.interaction;return h.options.find((t=>!t.hidden&&!t.classList.add("active"))),h.type=()=>h.options.find((t=>t.classList.contains("active"))),p})(this),t.useAsButton&&(this._root.button=t.el),t.container.appendChild(this._root.root);}_finalBuild(){const t=this.options,e=this._root;if(t.container.removeChild(e.root),t.inline){const o=t.el.parentElement;t.el.nextSibling?o.insertBefore(e.app,t.el.nextSibling):o.appendChild(e.app);}else t.container.appendChild(e.app);t.useAsButton?t.inline&&t.el.remove():t.el.parentNode.replaceChild(e.root,t.el),t.disabled&&this.disable(),t.comparison||(e.button.style.transition="none",t.useAsButton||(e.preview.lastColor.style.transition="none")),this.hide();}_buildComponents(){const t=this,e=this.options.components,o=(t.options.sliders||"v").repeat(2),[n,i]=o.match(/^[vh]+$/g)?o:[],s=()=>this._color||(this._color=this._lastColor.clone()),r={palette:S({element:t._root.palette.picker,wrapper:t._root.palette.palette,onstop:()=>t._emit("changestop","slider",t),onchange(o,n){if(!e.palette)return;const i=s(),{_root:r,options:a}=t,{lastColor:l,currentColor:c}=r.preview;t._recalc&&(i.s=100*o,i.v=100-100*n,i.v<0&&(i.v=0),t._updateOutput("slider"));const p=i.toRGBA().toString(0);this.element.style.background=p,this.wrapper.style.background=`\n linear-gradient(to top, rgba(0, 0, 0, ${i.a}), transparent),\n linear-gradient(to left, hsla(${i.h}, 100%, 50%, ${i.a}), rgba(255, 255, 255, ${i.a}))\n `,a.comparison?a.useAsButton||t._lastColor||l.style.setProperty("--pcr-color",p):(r.button.style.setProperty("--pcr-color",p),r.button.classList.remove("clear"));const h=i.toHEXA().toString();for(const{el:e,color:o}of t._swatchColors)e.classList[h===o.toHEXA().toString()?"add":"remove"]("pcr-active");c.style.setProperty("--pcr-color",p);}}),hue:S({lock:"v"===i?"h":"v",element:t._root.hue.picker,wrapper:t._root.hue.slider,onstop:()=>t._emit("changestop","slider",t),onchange(o){if(!e.hue||!e.palette)return;const n=s();t._recalc&&(n.h=360*o),this.element.style.backgroundColor=`hsl(${n.h}, 100%, 50%)`,r.palette.trigger();}}),opacity:S({lock:"v"===n?"h":"v",element:t._root.opacity.picker,wrapper:t._root.opacity.slider,onstop:()=>t._emit("changestop","slider",t),onchange(o){if(!e.opacity||!e.palette)return;const n=s();t._recalc&&(n.a=Math.round(100*o)/100),this.element.style.background=`rgba(0, 0, 0, ${n.a})`,r.palette.trigger();}}),selectable:O({elements:t._root.interaction.options,className:"active",onchange(e){t._representation=e.target.getAttribute("data-type").toUpperCase(),t._recalc&&t._updateOutput("swatch");}})};this._components=r;}_bindEvents(){const{_root:t,options:e}=this,o=[i(t.interaction.clear,"click",(()=>this._clearColor())),i([t.interaction.cancel,t.preview.lastColor],"click",(()=>{this.setHSVA(...(this._lastColor||this._color).toHSVA(),!0),this._emit("cancel");})),i(t.interaction.save,"click",(()=>{!this.applyColor()&&!e.showAlways&&this.hide();})),i(t.interaction.result,["keyup","input"],(t=>{this.setColor(t.target.value,!0)&&!this._initializingActive&&(this._emit("change",this._color,"input",this),this._emit("changestop","input",this)),t.stopImmediatePropagation();})),i(t.interaction.result,["focus","blur"],(t=>{this._recalc="blur"===t.type,this._recalc&&this._updateOutput(null);})),i([t.palette.palette,t.palette.picker,t.hue.slider,t.hue.picker,t.opacity.slider,t.opacity.picker],["mousedown","touchstart"],(()=>this._recalc=!0),{passive:!0})];if(!e.showAlways){const n=e.closeWithKey;o.push(i(t.button,"click",(()=>this.isOpen()?this.hide():this.show())),i(document,"keyup",(t=>this.isOpen()&&(t.key===n||t.code===n)&&this.hide())),i(document,["touchstart","mousedown"],(e=>{this.isOpen()&&!l(e).some((e=>e===t.app||e===t.button))&&this.hide();}),{capture:!0}));}if(e.adjustableNumbers){const e={rgba:[255,255,255,1],hsva:[360,100,100,1],hsla:[360,100,100,1],cmyk:[100,100,100,100]};p(t.interaction.result,((t,o,n)=>{const i=e[this.getColorRepresentation().toLowerCase()];if(i){const e=i[n],s=t+(e>=100?1e3*o:o);return s<=0?0:Number((s<e?s:e).toPrecision(3))}return t}));}if(e.autoReposition&&!e.inline){let t=null;const n=this;o.push(i(window,["scroll","resize"],(()=>{n.isOpen()&&(e.closeOnScroll&&n.hide(),null===t?(t=setTimeout((()=>t=null),100),requestAnimationFrame((function e(){n._rePositioningPicker(),null!==t&&requestAnimationFrame(e);}))):(clearTimeout(t),t=setTimeout((()=>t=null),100)));}),{capture:!0}));}this._eventBindings=o;}_rePositioningPicker(){const{options:t}=this;if(!t.inline){if(!this._nanopop.update({container:document.body.getBoundingClientRect(),position:t.position})){const t=this._root.app,e=t.getBoundingClientRect();t.style.top=(window.innerHeight-e.height)/2+"px",t.style.left=(window.innerWidth-e.width)/2+"px";}}}_updateOutput(t){const{_root:e,_color:o,options:n}=this;if(e.interaction.type()){const t=`to${e.interaction.type().getAttribute("data-type")}`;e.interaction.result.value="function"==typeof o[t]?o[t]().toString(n.outputPrecision):"";}!this._initializingActive&&this._recalc&&this._emit("change",o,t,this);}_clearColor(){let t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const{_root:e,options:o}=this;o.useAsButton||e.button.style.setProperty("--pcr-color","rgba(0, 0, 0, 0.15)"),e.button.classList.add("clear"),o.showAlways||this.hide(),this._lastColor=null,this._initializingActive||t||(this._emit("save",null),this._emit("clear"));}_parseLocalColor(t){const{values:e,type:o,a:n}=C(t),{lockOpacity:i}=this.options,s=void 0!==n&&1!==n;return e&&3===e.length&&(e[3]=void 0),{values:!e||i&&s?null:e,type:o}}_t(t){return this.options.i18n[t]||x.I18N_DEFAULTS[t]}_emit(t){for(var e=arguments.length,o=new Array(e>1?e-1:0),n=1;n<e;n++)o[n-1]=arguments[n];this._eventListener[t].forEach((t=>t(...o,this)));}on(t,e){return this._eventListener[t].push(e),this}off(t,e){const o=this._eventListener[t]||[],n=o.indexOf(e);return ~n&&o.splice(n,1),this}addSwatch(t){const{values:e}=this._parseLocalColor(t);if(e){const{_swatchColors:t,_root:o}=this,n=$(...e),s=r(`<button type="button" style="--pcr-color: ${n.toRGBA().toString(0)}" aria-label="${this._t("btn:swatch")}"/>`);return o.swatches.appendChild(s),t.push({el:s,color:n}),this._eventBindings.push(i(s,"click",(()=>{this.setHSVA(...n.toHSVA(),!0),this._emit("swatchselect",n),this._emit("change",n,"swatch",this);}))),!0}return !1}removeSwatch(t){const e=this._swatchColors[t];if(e){const{el:o}=e;return this._root.swatches.removeChild(o),this._swatchColors.splice(t,1),!0}return !1}applyColor(){let t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const{preview:e,button:o}=this._root,n=this._color.toRGBA().toString(0);return e.lastColor.style.setProperty("--pcr-color",n),this.options.useAsButton||o.style.setProperty("--pcr-color",n),o.classList.remove("clear"),this._lastColor=this._color.clone(),this._initializingActive||t||this._emit("save",this._color),this}destroy(){cancelAnimationFrame(this._setupAnimationFrame),this._eventBindings.forEach((t=>s(...t))),Object.keys(this._components).forEach((t=>this._components[t].destroy()));}destroyAndRemove(){this.destroy();const{root:t,app:e}=this._root;t.parentElement&&t.parentElement.removeChild(t),e.parentElement.removeChild(e),Object.keys(this).forEach((t=>this[t]=null));}hide(){return !!this.isOpen()&&(this._root.app.classList.remove("visible"),this._emit("hide"),!0)}show(){return !this.options.disabled&&!this.isOpen()&&(this._root.app.classList.add("visible"),this._rePositioningPicker(),this._emit("show",this._color),this)}isOpen(){return this._root.app.classList.contains("visible")}setHSVA(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:360,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:1,i=arguments.length>4&&void 0!==arguments[4]&&arguments[4];const s=this._recalc;if(this._recalc=!1,t<0||t>360||e<0||e>100||o<0||o>100||n<0||n>1)return !1;this._color=$(t,e,o,n);const{hue:r,opacity:a,palette:l}=this._components;return r.update(t/360),a.update(n),l.update(e/100,1-o/100),i||this.applyColor(),s&&this._updateOutput(),this._recalc=s,!0}setColor(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(null===t)return this._clearColor(e),!0;const{values:o,type:n}=this._parseLocalColor(t);if(o){const t=n.toUpperCase(),{options:i}=this._root.interaction,s=i.find((e=>e.getAttribute("data-type")===t));if(s&&!s.hidden)for(const t of i)t.classList[t===s?"add":"remove"]("active");return !!this.setHSVA(...o,e)&&this.setColorRepresentation(t)}return !1}setColorRepresentation(t){return t=t.toUpperCase(),!!this._root.interaction.options.find((e=>e.getAttribute("data-type").startsWith(t)&&!e.click()))}getColorRepresentation(){return this._representation}getColor(){return this._color}getSelectedColor(){return this._lastColor}getRoot(){return this._root}disable(){return this.hide(),this.options.disabled=!0,this._root.button.classList.add("disabled"),this}enable(){return this.options.disabled=!1,this._root.button.classList.remove("disabled"),this}}return P(x,"utils",o),P(x,"version","1.8.4"),P(x,"I18N_DEFAULTS",{"ui:dialog":"color picker dialog","btn:toggle":"toggle color picker dialog","btn:swatch":"color swatch","btn:last-color":"use previous color","btn:save":"Save","btn:cancel":"Cancel","btn:clear":"Clear","aria:btn:save":"save and close","aria:btn:cancel":"cancel and close","aria:btn:clear":"clear and close","aria:input":"color input field","aria:palette":"color selection area","aria:hue":"hue selection slider","aria:opacity":"selection slider"}),P(x,"DEFAULT_OPTIONS",{appClass:null,theme:"classic",useAsButton:!1,padding:8,disabled:!1,comparison:!0,closeOnScroll:!1,outputPrecision:0,lockOpacity:!1,autoReposition:!0,container:"body",components:{interaction:{}},i18n:{},swatches:null,inline:!1,sliders:null,default:"#42445a",defaultRepresentation:null,position:"bottom-middle",adjustableNumbers:!0,showAlways:!1,closeWithKey:"Escape"}),P(x,"create",(t=>new x(t))),e=e.default})()})); 4778 4779 }); 4780 4781 var Pickr = /*@__PURE__*/getDefaultExportFromCjs(pickr_min); 4782 4783 class VariableColorSettingComponent extends AbstractSettingComponent { 4784 render() { 4785 var _a; 4786 const title = getTitle(this.setting); 4787 const description = getDescription(this.setting); 4788 if (typeof this.setting.default !== 'string' || 4789 !isValidDefaultColor(this.setting.default)) { 4790 this.setting.default = (_a = this.settingsManager.plugin 4791 .getCSSVar(this.setting.id) 4792 .current) === null || _a === void 0 ? void 0 : _a.trim(); 4793 } 4794 if (typeof this.setting.default !== 'string' || 4795 !isValidDefaultColor(this.setting.default)) { 4796 return console.error(`${t('Error:')} ${title} ${t('missing default value, or value is not in a valid color format')}`); 4797 } 4798 const value = this.settingsManager.getSetting(this.sectionId, this.setting.id); 4799 const swatches = []; 4800 if (this.setting.default) { 4801 swatches.push(this.setting.default); 4802 } 4803 if (value !== undefined) { 4804 swatches.push(value); 4805 } 4806 this.settingEl = new obsidian.Setting(this.containerEl); 4807 this.settingEl.setName(title); 4808 this.settingEl.setDesc(createDescription(description, this.setting.default)); 4809 // fix, so that the color is correctly shown before the color picker has been opened 4810 const defaultColor = value !== undefined ? value : this.setting.default; 4811 this.containerEl.style.setProperty('--pcr-color', defaultColor); 4812 this.pickr = Pickr.create(getPickrSettings({ 4813 isView: this.isView, 4814 el: this.settingEl.controlEl.createDiv({ cls: 'picker' }), 4815 containerEl: this.containerEl, 4816 swatches: swatches, 4817 opacity: this.setting.opacity, 4818 defaultColor: defaultColor, 4819 })); 4820 this.pickr.on('save', (color, instance) => { 4821 if (!color) 4822 return; 4823 this.settingsManager.setSetting(this.sectionId, this.setting.id, color.toHEXA().toString()); 4824 instance.hide(); 4825 instance.addSwatch(color.toHEXA().toString()); 4826 }); 4827 this.pickr.on('show', () => { 4828 const { result } = this.pickr.getRoot().interaction; 4829 activeWindow.requestAnimationFrame(() => { 4830 activeWindow.requestAnimationFrame(() => result.select()); 4831 }); 4832 }); 4833 this.pickr.on('cancel', onPickrCancel); 4834 this.settingEl.addExtraButton((b) => { 4835 b.setIcon('reset'); 4836 b.onClick(() => { 4837 this.pickr.setColor(this.setting.default); 4838 this.settingsManager.clearSetting(this.sectionId, this.setting.id); 4839 }); 4840 b.setTooltip(resetTooltip); 4841 }); 4842 this.settingEl.settingEl.dataset.id = this.setting.id; 4843 } 4844 destroy() { 4845 var _a, _b; 4846 (_a = this.pickr) === null || _a === void 0 ? void 0 : _a.destroyAndRemove(); 4847 this.pickr = undefined; 4848 (_b = this.settingEl) === null || _b === void 0 ? void 0 : _b.settingEl.remove(); 4849 } 4850 } 4851 4852 class VariableNumberSettingComponent extends AbstractSettingComponent { 4853 render() { 4854 const title = getTitle(this.setting); 4855 const description = getDescription(this.setting); 4856 if (typeof this.setting.default !== 'number') { 4857 return console.error(`${t('Error:')} ${title} ${t('missing default value')}`); 4858 } 4859 this.settingEl = new obsidian.Setting(this.containerEl); 4860 this.settingEl.setName(title); 4861 this.settingEl.setDesc(createDescription(description, this.setting.default.toString(10))); 4862 this.settingEl.addText((text) => { 4863 const value = this.settingsManager.getSetting(this.sectionId, this.setting.id); 4864 const onChange = obsidian.debounce((value) => { 4865 const isFloat = /\./.test(value); 4866 this.settingsManager.setSetting(this.sectionId, this.setting.id, isFloat ? parseFloat(value) : parseInt(value, 10)); 4867 }, 250, true); 4868 text.setValue(value !== undefined ? value.toString() : this.setting.default.toString()); 4869 text.onChange(onChange); 4870 this.textComponent = text; 4871 }); 4872 this.settingEl.addExtraButton((b) => { 4873 b.setIcon('reset'); 4874 b.onClick(() => { 4875 this.textComponent.setValue(this.setting.default.toString()); 4876 this.settingsManager.clearSetting(this.sectionId, this.setting.id); 4877 }); 4878 b.setTooltip(resetTooltip); 4879 }); 4880 this.settingEl.settingEl.dataset.id = this.setting.id; 4881 } 4882 destroy() { 4883 var _a; 4884 (_a = this.settingEl) === null || _a === void 0 ? void 0 : _a.settingEl.remove(); 4885 } 4886 } 4887 4888 class VariableNumberSliderSettingComponent extends AbstractSettingComponent { 4889 render() { 4890 const title = getTitle(this.setting); 4891 const description = getDescription(this.setting); 4892 if (typeof this.setting.default !== 'number') { 4893 return console.error(`${t('Error:')} ${title} ${t('missing default value')}`); 4894 } 4895 this.settingEl = new obsidian.Setting(this.containerEl); 4896 this.settingEl.setName(title); 4897 this.settingEl.setDesc(createDescription(description, this.setting.default.toString(10))); 4898 this.settingEl.addSlider((slider) => { 4899 const value = this.settingsManager.getSetting(this.sectionId, this.setting.id); 4900 const onChange = obsidian.debounce((value) => { 4901 this.settingsManager.setSetting(this.sectionId, this.setting.id, value); 4902 }, 250, true); 4903 slider.setDynamicTooltip(); 4904 slider.setLimits(this.setting.min, this.setting.max, this.setting.step); 4905 slider.setValue(value !== undefined ? value : this.setting.default); 4906 slider.onChange(onChange); 4907 this.sliderComponent = slider; 4908 }); 4909 this.settingEl.addExtraButton((b) => { 4910 b.setIcon('reset'); 4911 b.onClick(() => { 4912 this.sliderComponent.setValue(this.setting.default); 4913 this.settingsManager.clearSetting(this.sectionId, this.setting.id); 4914 }); 4915 b.setTooltip(resetTooltip); 4916 }); 4917 this.settingEl.settingEl.dataset.id = this.setting.id; 4918 } 4919 destroy() { 4920 var _a; 4921 (_a = this.settingEl) === null || _a === void 0 ? void 0 : _a.settingEl.remove(); 4922 } 4923 } 4924 4925 class VariableSelectSettingComponent extends AbstractSettingComponent { 4926 render() { 4927 const title = getTitle(this.setting); 4928 const description = getDescription(this.setting); 4929 if (typeof this.setting.default !== 'string') { 4930 return console.error(`${t('Error:')} ${title} ${t('missing default value')}`); 4931 } 4932 const defaultLabel = this.getDefaultOptionLabel(); 4933 this.settingEl = new obsidian.Setting(this.containerEl); 4934 this.settingEl.setName(title); 4935 this.settingEl.setDesc(createDescription(description, this.setting.default, defaultLabel)); 4936 this.settingEl.addDropdown((dropdown) => { 4937 const value = this.settingsManager.getSetting(this.sectionId, this.setting.id); 4938 for (const o of this.setting.options) { 4939 if (typeof o === 'string') { 4940 dropdown.addOption(o, o); 4941 } 4942 else { 4943 dropdown.addOption(o.value, o.label); 4944 } 4945 } 4946 dropdown.setValue(value !== undefined ? value : this.setting.default); 4947 dropdown.onChange((value) => { 4948 this.settingsManager.setSetting(this.sectionId, this.setting.id, value); 4949 }); 4950 this.dropdownComponent = dropdown; 4951 }); 4952 this.settingEl.addExtraButton((b) => { 4953 b.setIcon('reset'); 4954 b.onClick(() => { 4955 this.dropdownComponent.setValue(this.setting.default); 4956 this.settingsManager.clearSetting(this.sectionId, this.setting.id); 4957 }); 4958 b.setTooltip(resetTooltip); 4959 }); 4960 this.settingEl.settingEl.dataset.id = this.setting.id; 4961 } 4962 destroy() { 4963 var _a; 4964 (_a = this.settingEl) === null || _a === void 0 ? void 0 : _a.settingEl.remove(); 4965 } 4966 getDefaultOption() { 4967 if (this.setting.default) { 4968 return this.setting.options.find((o) => { 4969 if (typeof o === 'string') { 4970 return o === this.setting.default; 4971 } 4972 return o.value === this.setting.default; 4973 }); 4974 } 4975 return undefined; 4976 } 4977 getDefaultOptionLabel() { 4978 const defaultOption = this.getDefaultOption(); 4979 if (defaultOption) { 4980 if (typeof defaultOption === 'string') { 4981 return defaultOption; 4982 } 4983 return defaultOption.label; 4984 } 4985 return undefined; 4986 } 4987 } 4988 4989 class VariableTextSettingComponent extends AbstractSettingComponent { 4990 render() { 4991 const title = getTitle(this.setting); 4992 const description = getDescription(this.setting); 4993 if (typeof this.setting.default !== 'string') { 4994 return console.error(`${t('Error:')} ${title} ${t('missing default value')}`); 4995 } 4996 this.settingEl = new obsidian.Setting(this.containerEl); 4997 this.settingEl.setName(title); 4998 this.settingEl.setDesc(createDescription(description, this.setting.default)); 4999 this.settingEl.addText((text) => { 5000 let value = this.settingsManager.getSetting(this.sectionId, this.setting.id); 5001 const onChange = obsidian.debounce((value) => { 5002 this.settingsManager.setSetting(this.sectionId, this.setting.id, sanitizeText(value)); 5003 }, 250, true); 5004 if (this.setting.quotes && value === `""`) { 5005 value = ``; 5006 } 5007 text.setValue(value ? value.toString() : this.setting.default); 5008 text.onChange(onChange); 5009 this.textComponent = text; 5010 }); 5011 this.settingEl.addExtraButton((b) => { 5012 b.setIcon('reset'); 5013 b.onClick(() => { 5014 this.textComponent.setValue(this.setting.default); 5015 this.settingsManager.clearSetting(this.sectionId, this.setting.id); 5016 }); 5017 b.setTooltip(resetTooltip); 5018 }); 5019 this.settingEl.settingEl.dataset.id = this.setting.id; 5020 } 5021 destroy() { 5022 var _a; 5023 (_a = this.settingEl) === null || _a === void 0 ? void 0 : _a.settingEl.remove(); 5024 } 5025 } 5026 5027 class VariableThemedColorSettingComponent extends AbstractSettingComponent { 5028 render() { 5029 const title = getTitle(this.setting); 5030 const description = getDescription(this.setting); 5031 if (typeof this.setting['default-light'] !== 'string' || 5032 !isValidDefaultColor(this.setting['default-light'])) { 5033 return console.error(`${t('Error:')} ${title} ${t('missing default light value, or value is not in a valid color format')}`); 5034 } 5035 if (typeof this.setting['default-dark'] !== 'string' || 5036 !isValidDefaultColor(this.setting['default-dark'])) { 5037 return console.error(`${t('Error:')} ${title} ${t('missing default dark value, or value is not in a valid color format')}`); 5038 } 5039 const idLight = `${this.setting.id}@@light`; 5040 const idDark = `${this.setting.id}@@dark`; 5041 const valueLight = this.settingsManager.getSetting(this.sectionId, idLight); 5042 const valueDark = this.settingsManager.getSetting(this.sectionId, idDark); 5043 const swatchesLight = []; 5044 const swatchesDark = []; 5045 if (this.setting['default-light']) { 5046 swatchesLight.push(this.setting['default-light']); 5047 } 5048 if (valueLight !== undefined) { 5049 swatchesLight.push(valueLight); 5050 } 5051 if (this.setting['default-dark']) { 5052 swatchesDark.push(this.setting['default-dark']); 5053 } 5054 if (valueDark !== undefined) { 5055 swatchesDark.push(valueDark); 5056 } 5057 this.settingEl = new obsidian.Setting(this.containerEl); 5058 this.settingEl.setName(title); 5059 // Construct description 5060 this.settingEl.descEl.createSpan({}, (span) => { 5061 if (description) { 5062 span.appendChild(document.createTextNode(description)); 5063 } 5064 }); 5065 this.settingEl.descEl.createDiv({}, (div) => { 5066 div.createEl('small', {}, (sm) => { 5067 sm.appendChild(createEl('strong', { text: 'Default (light): ' })); 5068 sm.appendChild(document.createTextNode(this.setting['default-light'])); 5069 }); 5070 div.createEl('br'); 5071 div.createEl('small', {}, (sm) => { 5072 sm.appendChild(createEl('strong', { text: 'Default (dark): ' })); 5073 sm.appendChild(document.createTextNode(this.setting['default-dark'])); 5074 }); 5075 }); 5076 const wrapper = this.settingEl.controlEl.createDiv({ 5077 cls: 'themed-color-wrapper', 5078 }); 5079 // Create light color picker 5080 this.createColorPickerLight(wrapper, this.containerEl, swatchesLight, valueLight, idLight); 5081 // Create dark color picker 5082 this.createColorPickerDark(wrapper, this.containerEl, swatchesDark, valueDark, idDark); 5083 this.settingEl.settingEl.dataset.id = this.setting.id; 5084 } 5085 destroy() { 5086 var _a, _b, _c; 5087 (_a = this.pickrLight) === null || _a === void 0 ? void 0 : _a.destroyAndRemove(); 5088 (_b = this.pickrDark) === null || _b === void 0 ? void 0 : _b.destroyAndRemove(); 5089 this.pickrLight = undefined; 5090 this.pickrDark = undefined; 5091 (_c = this.settingEl) === null || _c === void 0 ? void 0 : _c.settingEl.remove(); 5092 } 5093 createColorPickerLight(wrapper, containerEl, swatchesLight, valueLight, idLight) { 5094 const themeLightWrapper = wrapper.createDiv({ cls: 'theme-light' }); 5095 // fix, so that the color is correctly shown before the color picker has been opened 5096 const defaultColor = valueLight !== undefined 5097 ? valueLight 5098 : this.setting['default-light']; 5099 themeLightWrapper.style.setProperty('--pcr-color', defaultColor); 5100 this.pickrLight = Pickr.create(getPickrSettings({ 5101 isView: this.isView, 5102 el: themeLightWrapper.createDiv({ cls: 'picker' }), 5103 containerEl, 5104 swatches: swatchesLight, 5105 opacity: this.setting.opacity, 5106 defaultColor: defaultColor, 5107 })); 5108 this.pickrLight.on('show', () => { 5109 const { result } = this.pickrLight.getRoot().interaction; 5110 activeWindow.requestAnimationFrame(() => activeWindow.requestAnimationFrame(() => result.select())); 5111 }); 5112 this.pickrLight.on('save', (color, instance) => this.onSave(idLight, color, instance)); 5113 this.pickrLight.on('cancel', onPickrCancel); 5114 const themeLightReset = new obsidian.ButtonComponent(themeLightWrapper.createDiv({ cls: 'pickr-reset' })); 5115 themeLightReset.setIcon('reset'); 5116 themeLightReset.onClick(() => { 5117 this.pickrLight.setColor(this.setting['default-light']); 5118 this.settingsManager.clearSetting(this.sectionId, idLight); 5119 }); 5120 themeLightReset.setTooltip(resetTooltip); 5121 } 5122 createColorPickerDark(wrapper, containerEl, swatchesDark, valueDark, idDark) { 5123 const themeDarkWrapper = wrapper.createDiv({ cls: 'theme-dark' }); 5124 // fix, so that the color is correctly shown before the color picker has been opened 5125 const defaultColor = valueDark !== undefined 5126 ? valueDark 5127 : this.setting['default-dark']; 5128 themeDarkWrapper.style.setProperty('--pcr-color', defaultColor); 5129 this.pickrDark = Pickr.create(getPickrSettings({ 5130 isView: this.isView, 5131 el: themeDarkWrapper.createDiv({ cls: 'picker' }), 5132 containerEl, 5133 swatches: swatchesDark, 5134 opacity: this.setting.opacity, 5135 defaultColor: defaultColor, 5136 })); 5137 this.pickrDark.on('show', () => { 5138 const { result } = this.pickrDark.getRoot().interaction; 5139 activeWindow.requestAnimationFrame(() => activeWindow.requestAnimationFrame(() => result.select())); 5140 }); 5141 this.pickrDark.on('save', (color, instance) => this.onSave(idDark, color, instance)); 5142 this.pickrDark.on('cancel', onPickrCancel); 5143 const themeDarkReset = new obsidian.ButtonComponent(themeDarkWrapper.createDiv({ cls: 'pickr-reset' })); 5144 themeDarkReset.setIcon('reset'); 5145 themeDarkReset.onClick(() => { 5146 this.pickrDark.setColor(this.setting['default-dark']); 5147 this.settingsManager.clearSetting(this.sectionId, idDark); 5148 }); 5149 themeDarkReset.setTooltip(resetTooltip); 5150 } 5151 onSave(id, color, instance) { 5152 if (!color) 5153 return; 5154 this.settingsManager.setSetting(this.sectionId, id, color.toHEXA().toString()); 5155 instance.hide(); 5156 instance.addSwatch(color.toHEXA().toString()); 5157 } 5158 } 5159 5160 function createSettingComponent(parent, sectionId, sectionName, setting, settingsManager, isView) { 5161 if (setting.type === SettingType.HEADING) { 5162 return new HeadingSettingComponent(parent, sectionId, sectionName, setting, settingsManager, isView); 5163 } 5164 else if (setting.type === SettingType.INFO_TEXT) { 5165 return new InfoTextSettingComponent(parent, sectionId, sectionName, setting, settingsManager, isView); 5166 } 5167 else if (setting.type === SettingType.CLASS_TOGGLE) { 5168 return new ClassToggleSettingComponent(parent, sectionId, sectionName, setting, settingsManager, isView); 5169 } 5170 else if (setting.type === SettingType.CLASS_SELECT) { 5171 return new ClassMultiToggleSettingComponent(parent, sectionId, sectionName, setting, settingsManager, isView); 5172 } 5173 else if (setting.type === SettingType.VARIABLE_TEXT) { 5174 return new VariableTextSettingComponent(parent, sectionId, sectionName, setting, settingsManager, isView); 5175 } 5176 else if (setting.type === SettingType.VARIABLE_NUMBER) { 5177 return new VariableNumberSettingComponent(parent, sectionId, sectionName, setting, settingsManager, isView); 5178 } 5179 else if (setting.type === SettingType.VARIABLE_NUMBER_SLIDER) { 5180 return new VariableNumberSliderSettingComponent(parent, sectionId, sectionName, setting, settingsManager, isView); 5181 } 5182 else if (setting.type === SettingType.VARIABLE_SELECT) { 5183 return new VariableSelectSettingComponent(parent, sectionId, sectionName, setting, settingsManager, isView); 5184 } 5185 else if (setting.type === SettingType.VARIABLE_COLOR) { 5186 return new VariableColorSettingComponent(parent, sectionId, sectionName, setting, settingsManager, isView); 5187 } 5188 else if (setting.type === SettingType.VARIABLE_THEMED_COLOR) { 5189 return new VariableThemedColorSettingComponent(parent, sectionId, sectionName, setting, settingsManager, isView); 5190 } 5191 else { 5192 return undefined; 5193 } 5194 } 5195 function buildSettingComponentTree(opts) { 5196 const { containerEl, isView, sectionId, settings, settingsManager, sectionName, } = opts; 5197 const root = new HeadingSettingComponent(containerEl, sectionId, sectionName, settings[0], settingsManager, isView); 5198 let currentHeading = root; 5199 for (const setting of settings.splice(1)) { 5200 if (setting.type === 'heading') { 5201 const newHeading = setting; 5202 if (newHeading.level < currentHeading.setting.level) { 5203 while (newHeading.level < currentHeading.setting.level) { 5204 currentHeading = currentHeading.parent; 5205 } 5206 if (currentHeading.setting.id === root.setting.id) { 5207 currentHeading = currentHeading.addSettingChild(newHeading); 5208 } 5209 else { 5210 currentHeading = currentHeading.parent.addSettingChild(newHeading); 5211 } 5212 } 5213 else if (newHeading.level === currentHeading.setting.level) { 5214 currentHeading = currentHeading.parent.addSettingChild(newHeading); 5215 } 5216 else { 5217 currentHeading = currentHeading.addSettingChild(newHeading); 5218 } 5219 } 5220 else { 5221 currentHeading.addSettingChild(setting); 5222 } 5223 } 5224 return root; 5225 } 5226 class HeadingSettingComponent extends AbstractSettingComponent { 5227 constructor() { 5228 super(...arguments); 5229 this.children = []; 5230 this.filteredChildren = []; 5231 this.filterMode = false; 5232 this.filterResultCount = 0; 5233 } 5234 render() { 5235 const title = getTitle(this.setting); 5236 const description = getDescription(this.setting); 5237 this.settingEl = new obsidian.Setting(this.containerEl); 5238 this.settingEl.setHeading(); 5239 this.settingEl.setClass('style-settings-heading'); 5240 this.settingEl.setName(title); 5241 this.settingEl.setDesc(description !== null && description !== void 0 ? description : ''); 5242 this.settingEl.settingEl.dataset.level = this.setting.level.toString(); 5243 this.settingEl.settingEl.dataset.id = this.setting.id; 5244 const iconContainer = createSpan({ 5245 cls: 'style-settings-collapse-indicator', 5246 }); 5247 obsidian.setIcon(iconContainer, 'right-triangle'); 5248 this.settingEl.nameEl.prepend(iconContainer); 5249 this.resultsEl = this.settingEl.nameEl.createSpan({ 5250 cls: 'style-settings-filter-result-count', 5251 text: this.filterMode ? `${this.filterResultCount} Results` : undefined, 5252 }); 5253 this.settingEl.settingEl.addEventListener('click', () => { 5254 this.toggleVisible(); 5255 }); 5256 this.addResetButton(); 5257 this.addExportButton(); 5258 this.childEl = this.containerEl.createDiv({ 5259 cls: 'style-settings-container', 5260 }); 5261 this.setCollapsed(this.setting.collapsed); 5262 } 5263 destroy() { 5264 var _a; 5265 this.removeChildren(); 5266 (_a = this.settingEl) === null || _a === void 0 ? void 0 : _a.settingEl.remove(); 5267 this.childEl.remove(); 5268 } 5269 filter(filterString) { 5270 var _a; 5271 this.filteredChildren = []; 5272 this.filterResultCount = 0; 5273 for (const child of this.children) { 5274 if (child.setting.type === SettingType.HEADING) { 5275 const childResultCount = child.filter(filterString); 5276 if (childResultCount > 0) { 5277 this.filterResultCount += childResultCount; 5278 this.filteredChildren.push(child); 5279 } 5280 } 5281 else { 5282 if (child.decisiveMatch(filterString)) { 5283 this.filteredChildren.push(child); 5284 this.filterResultCount += 1; 5285 } 5286 } 5287 } 5288 this.filterMode = true; 5289 if (this.filterResultCount) { 5290 this.setCollapsed(false); 5291 } 5292 else { 5293 this.setCollapsed(true); 5294 } 5295 this.renderChildren(); 5296 (_a = this.resultsEl) === null || _a === void 0 ? void 0 : _a.setText(`${this.filterResultCount} Results`); 5297 return this.filterResultCount; 5298 } 5299 clearFilter() { 5300 var _a; 5301 this.filteredChildren = []; 5302 for (const child of this.children) { 5303 if (child.setting.type === SettingType.HEADING) { 5304 child.clearFilter(); 5305 } 5306 } 5307 this.filterMode = false; 5308 this.setCollapsed(true); 5309 this.renderChildren(); 5310 (_a = this.resultsEl) === null || _a === void 0 ? void 0 : _a.empty(); 5311 } 5312 renderChildren() { 5313 this.removeChildren(); 5314 if (this.filterMode) { 5315 for (const child of this.filteredChildren) { 5316 this.addChild(child); 5317 } 5318 } 5319 else { 5320 for (const child of this.children) { 5321 this.addChild(child); 5322 } 5323 } 5324 } 5325 removeChildren() { 5326 for (const child of this.children) { 5327 this.removeChild(child); 5328 } 5329 } 5330 toggleVisible() { 5331 this.setCollapsed(!this.setting.collapsed); 5332 } 5333 setCollapsed(collapsed) { 5334 var _a; 5335 this.setting.collapsed = collapsed; 5336 (_a = this.settingEl) === null || _a === void 0 ? void 0 : _a.settingEl.toggleClass('is-collapsed', collapsed); 5337 if (collapsed) { 5338 this.removeChildren(); 5339 } 5340 else { 5341 this.renderChildren(); 5342 } 5343 } 5344 addResetButton() { 5345 if (this.setting.resetFn) { 5346 this.settingEl.addExtraButton((b) => { 5347 b.setIcon('reset') 5348 .setTooltip('Reset all settings to default') 5349 .onClick(this.setting.resetFn); 5350 }); 5351 } 5352 } 5353 addExportButton() { 5354 this.settingEl.addExtraButton((b) => { 5355 b.setIcon('install'); 5356 b.setTooltip('Export settings'); 5357 b.extraSettingsEl.onClickEvent((e) => { 5358 e.stopPropagation(); 5359 let title = getTitle(this.setting); 5360 title = 5361 this.sectionName === title ? title : `${this.sectionName} > ${title}`; 5362 this.settingsManager.export(title, this.settingsManager.getSettings(this.sectionId, this.getAllChildrenIds())); 5363 }); 5364 }); 5365 } 5366 addSettingChild(child) { 5367 const newSettingComponent = createSettingComponent(this, this.sectionId, this.sectionName, child, this.settingsManager, this.isView); 5368 if (!newSettingComponent) { 5369 return undefined; 5370 } 5371 this.children.push(newSettingComponent); 5372 return newSettingComponent; 5373 } 5374 getAllChildrenIds() { 5375 const children = []; 5376 for (const child of this.children) { 5377 children.push(child.setting.id); 5378 if (child.setting.type === 'heading') { 5379 children.push(...child.getAllChildrenIds()); 5380 } 5381 } 5382 return children; 5383 } 5384 } 5385 5386 class SettingsMarkup extends obsidian.Component { 5387 constructor(app, plugin, containerEl, isView) { 5388 super(); 5389 this.settingsComponentTrees = []; 5390 this.filterString = ''; 5391 this.settings = []; 5392 this.errorList = []; 5393 this.app = app; 5394 this.plugin = plugin; 5395 this.containerEl = containerEl; 5396 this.isView = !!isView; 5397 } 5398 onload() { 5399 this.display(); 5400 } 5401 onunload() { 5402 this.settingsComponentTrees = []; 5403 } 5404 display() { 5405 this.generate(this.settings); 5406 } 5407 removeChildren() { 5408 for (const settingsComponentTree of this.settingsComponentTrees) { 5409 this.removeChild(settingsComponentTree); 5410 } 5411 } 5412 /** 5413 * Recursively destroys all setting elements. 5414 */ 5415 cleanup() { 5416 var _a; 5417 this.removeChildren(); 5418 (_a = this.settingsContainerEl) === null || _a === void 0 ? void 0 : _a.empty(); 5419 } 5420 setSettings(settings, errorList) { 5421 this.settings = settings; 5422 this.errorList = errorList; 5423 if (this.containerEl.parentNode) { 5424 this.generate(settings); 5425 } 5426 } 5427 displayErrors() { 5428 const { containerEl, errorList } = this; 5429 errorList.forEach((err) => { 5430 containerEl.createDiv({ cls: 'style-settings-error' }, (wrapper) => { 5431 wrapper.createDiv({ 5432 cls: 'style-settings-error-name', 5433 text: `Error: ${err.name}`, 5434 }); 5435 wrapper.createDiv({ 5436 cls: 'style-settings-error-desc', 5437 text: err.error, 5438 }); 5439 }); 5440 }); 5441 } 5442 displayEmpty() { 5443 const { containerEl } = this; 5444 containerEl.createDiv({ cls: 'style-settings-empty' }, (wrapper) => { 5445 wrapper.createDiv({ 5446 cls: 'style-settings-empty-name', 5447 text: 'No style settings found', 5448 }); 5449 wrapper.createDiv({ cls: 'style-settings-empty-desc' }).appendChild(createFragment((frag) => { 5450 frag.appendText('Style settings configured by theme and plugin authors will show up here. You can also create your own configuration by creating a CSS snippet in your vault. '); 5451 frag.createEl('a', { 5452 text: 'Click here for details and examples.', 5453 href: 'https://github.com/mgmeyers/obsidian-style-settings#obsidian-style-settings-plugin', 5454 }); 5455 })); 5456 }); 5457 } 5458 generate(settings) { 5459 var _a; 5460 const { containerEl, plugin } = this; 5461 containerEl.empty(); 5462 this.cleanup(); 5463 this.displayErrors(); 5464 if (settings.length === 0) { 5465 return this.displayEmpty(); 5466 } 5467 new obsidian.Setting(containerEl).then((setting) => { 5468 // Build and import link to open the import modal 5469 setting.controlEl.createEl('a', { 5470 cls: 'style-settings-import', 5471 text: 'Import', 5472 href: '#', 5473 }, (el) => { 5474 el.addEventListener('click', (e) => { 5475 e.preventDefault(); 5476 this.plugin.settingsManager.import(); 5477 }); 5478 }); 5479 // Build and export link to open the export modal 5480 setting.controlEl.createEl('a', { 5481 cls: 'style-settings-export', 5482 text: 'Export', 5483 href: '#', 5484 }, (el) => { 5485 el.addEventListener('click', (e) => { 5486 e.preventDefault(); 5487 this.plugin.settingsManager.export('All settings', this.plugin.settingsManager.settings); 5488 }); 5489 }); 5490 // Searchbar 5491 let searchComponent; 5492 setting.addSearch((s) => { 5493 searchComponent = s; 5494 }); 5495 // move the search component from the back to the front 5496 setting.nameEl.appendChild(setting.controlEl.lastChild); 5497 searchComponent.setValue(this.filterString); 5498 searchComponent.onChange(obsidian.debounce((value) => { 5499 this.filterString = value; 5500 if (value) { 5501 this.filter(); 5502 } 5503 else { 5504 this.clearFilter(); 5505 } 5506 }, 250, true)); 5507 searchComponent.setPlaceholder('Search Style Settings...'); 5508 }); 5509 this.settingsContainerEl = containerEl.createDiv(); 5510 this.settingsComponentTrees = []; 5511 for (const s of settings) { 5512 const options = [ 5513 { 5514 id: s.id, 5515 type: 'heading', 5516 title: s.name, 5517 level: 0, 5518 collapsed: (_a = s.collapsed) !== null && _a !== void 0 ? _a : true, 5519 resetFn: () => { 5520 plugin.settingsManager.clearSection(s.id); 5521 this.rerender(); 5522 }, 5523 }, 5524 ...s.settings, 5525 ]; 5526 try { 5527 const settingsComponentTree = buildSettingComponentTree({ 5528 containerEl: this.settingsContainerEl, 5529 isView: this.isView, 5530 sectionId: s.id, 5531 sectionName: s.name, 5532 settings: options, 5533 settingsManager: plugin.settingsManager, 5534 }); 5535 this.addChild(settingsComponentTree); 5536 this.settingsComponentTrees.push(settingsComponentTree); 5537 } 5538 catch (e) { 5539 console.error('Style Settings | Failed to render section', e); 5540 } 5541 } 5542 } 5543 /** 5544 * Recursively filter all setting elements based on `filterString` and then re-renders. 5545 */ 5546 filter() { 5547 for (const settingsComponentTree of this.settingsComponentTrees) { 5548 settingsComponentTree.filter(this.filterString); 5549 } 5550 } 5551 /** 5552 * Recursively clears the filter and then re-renders. 5553 */ 5554 clearFilter() { 5555 for (const settingsComponentTree of this.settingsComponentTrees) { 5556 settingsComponentTree.clearFilter(); 5557 } 5558 } 5559 rerender() { 5560 this.cleanup(); 5561 this.display(); 5562 } 5563 } 5564 5565 class CSSSettingsTab extends obsidian.PluginSettingTab { 5566 constructor(app, plugin) { 5567 super(app, plugin); 5568 this.plugin = plugin; 5569 } 5570 rerender() { 5571 var _a; 5572 (_a = this.settingsMarkup) === null || _a === void 0 ? void 0 : _a.rerender(); 5573 } 5574 setSettings(settings, errorList) { 5575 this.settings = settings; 5576 this.errorList = errorList; 5577 if (this.settingsMarkup) { 5578 this.settingsMarkup.setSettings(settings, errorList); 5579 } 5580 } 5581 display() { 5582 this.settingsMarkup = this.plugin.addChild(new SettingsMarkup(this.app, this.plugin, this.containerEl)); 5583 if (this.settings) { 5584 this.settingsMarkup.setSettings(this.settings, this.errorList); 5585 } 5586 } 5587 hide() { 5588 this.plugin.removeChild(this.settingsMarkup); 5589 this.settingsMarkup = null; 5590 } 5591 } 5592 5593 const viewType = 'style-settings'; 5594 class SettingsView extends obsidian.ItemView { 5595 constructor(plugin, leaf) { 5596 super(leaf); 5597 this.plugin = plugin; 5598 } 5599 rerender() { 5600 var _a; 5601 (_a = this.settingsMarkup) === null || _a === void 0 ? void 0 : _a.rerender(); 5602 } 5603 setSettings(settings, errorList) { 5604 this.settings = settings; 5605 this.errorList = errorList; 5606 if (this.settingsMarkup) { 5607 this.settingsMarkup.setSettings(settings, errorList); 5608 } 5609 } 5610 onload() { 5611 this.settingsMarkup = this.addChild(new SettingsMarkup(this.plugin.app, this.plugin, this.contentEl, true)); 5612 if (this.settings) { 5613 this.settingsMarkup.setSettings(this.settings, this.errorList); 5614 } 5615 } 5616 onunload() { 5617 this.settingsMarkup = null; 5618 } 5619 getViewType() { 5620 return viewType; 5621 } 5622 getIcon() { 5623 return 'gear'; 5624 } 5625 getDisplayText() { 5626 return 'Style Settings'; 5627 } 5628 } 5629 5630 // Detect either spaces or tabs but not both to properly handle tabs for indentation and spaces for alignment 5631 const INDENT_REGEX = /^(?:( )+|\t+)/; 5632 5633 const INDENT_TYPE_SPACE = 'space'; 5634 const INDENT_TYPE_TAB = 'tab'; 5635 5636 /** 5637 Make a Map that counts how many indents/unindents have occurred for a given size and how many lines follow a given indentation. 5638 5639 The key is a concatenation of the indentation type (s = space and t = tab) and the size of the indents/unindents. 5640 5641 ``` 5642 indents = { 5643 t3: [1, 0], 5644 t4: [1, 5], 5645 s5: [1, 0], 5646 s12: [1, 0], 5647 } 5648 ``` 5649 */ 5650 function makeIndentsMap(string, ignoreSingleSpaces) { 5651 const indents = new Map(); 5652 5653 // Remember the size of previous line's indentation 5654 let previousSize = 0; 5655 let previousIndentType; 5656 5657 // Indents key (ident type + size of the indents/unindents) 5658 let key; 5659 5660 for (const line of string.split(/\n/g)) { 5661 if (!line) { 5662 // Ignore empty lines 5663 continue; 5664 } 5665 5666 let indent; 5667 let indentType; 5668 let weight; 5669 let entry; 5670 const matches = line.match(INDENT_REGEX); 5671 5672 if (matches === null) { 5673 previousSize = 0; 5674 previousIndentType = ''; 5675 } else { 5676 indent = matches[0].length; 5677 indentType = matches[1] ? INDENT_TYPE_SPACE : INDENT_TYPE_TAB; 5678 5679 // Ignore single space unless it's the only indent detected to prevent common false positives 5680 if (ignoreSingleSpaces && indentType === INDENT_TYPE_SPACE && indent === 1) { 5681 continue; 5682 } 5683 5684 if (indentType !== previousIndentType) { 5685 previousSize = 0; 5686 } 5687 5688 previousIndentType = indentType; 5689 5690 weight = 0; 5691 5692 const indentDifference = indent - previousSize; 5693 previousSize = indent; 5694 5695 // Previous line have same indent? 5696 if (indentDifference === 0) { 5697 weight++; 5698 // We use the key from previous loop 5699 } else { 5700 const absoluteIndentDifference = indentDifference > 0 ? indentDifference : -indentDifference; 5701 key = encodeIndentsKey(indentType, absoluteIndentDifference); 5702 } 5703 5704 // Update the stats 5705 entry = indents.get(key); 5706 entry = entry === undefined ? [1, 0] : [++entry[0], entry[1] + weight]; 5707 5708 indents.set(key, entry); 5709 } 5710 } 5711 5712 return indents; 5713 } 5714 5715 // Encode the indent type and amount as a string (e.g. 's4') for use as a compound key in the indents Map. 5716 function encodeIndentsKey(indentType, indentAmount) { 5717 const typeCharacter = indentType === INDENT_TYPE_SPACE ? 's' : 't'; 5718 return typeCharacter + String(indentAmount); 5719 } 5720 5721 // Extract the indent type and amount from a key of the indents Map. 5722 function decodeIndentsKey(indentsKey) { 5723 const keyHasTypeSpace = indentsKey[0] === 's'; 5724 const type = keyHasTypeSpace ? INDENT_TYPE_SPACE : INDENT_TYPE_TAB; 5725 5726 const amount = Number(indentsKey.slice(1)); 5727 5728 return {type, amount}; 5729 } 5730 5731 // Return the key (e.g. 's4') from the indents Map that represents the most common indent, 5732 // or return undefined if there are no indents. 5733 function getMostUsedKey(indents) { 5734 let result; 5735 let maxUsed = 0; 5736 let maxWeight = 0; 5737 5738 for (const [key, [usedCount, weight]] of indents) { 5739 if (usedCount > maxUsed || (usedCount === maxUsed && weight > maxWeight)) { 5740 maxUsed = usedCount; 5741 maxWeight = weight; 5742 result = key; 5743 } 5744 } 5745 5746 return result; 5747 } 5748 5749 function makeIndentString(type, amount) { 5750 const indentCharacter = type === INDENT_TYPE_SPACE ? ' ' : '\t'; 5751 return indentCharacter.repeat(amount); 5752 } 5753 5754 function detectIndent(string) { 5755 if (typeof string !== 'string') { 5756 throw new TypeError('Expected a string'); 5757 } 5758 5759 // Identify indents while skipping single space indents to avoid common edge cases (e.g. code comments) 5760 // If no indents are identified, run again and include all indents for comprehensive detection 5761 let indents = makeIndentsMap(string, true); 5762 if (indents.size === 0) { 5763 indents = makeIndentsMap(string, false); 5764 } 5765 5766 const keyOfMostUsedIndent = getMostUsedKey(indents); 5767 5768 let type; 5769 let amount = 0; 5770 let indent = ''; 5771 5772 if (keyOfMostUsedIndent !== undefined) { 5773 ({type, amount} = decodeIndentsKey(keyOfMostUsedIndent)); 5774 indent = makeIndentString(type, amount); 5775 } 5776 5777 return { 5778 amount, 5779 type, 5780 indent, 5781 }; 5782 } 5783 5784 /*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */ 5785 function isNothing(subject) { 5786 return (typeof subject === 'undefined') || (subject === null); 5787 } 5788 5789 5790 function isObject(subject) { 5791 return (typeof subject === 'object') && (subject !== null); 5792 } 5793 5794 5795 function toArray(sequence) { 5796 if (Array.isArray(sequence)) return sequence; 5797 else if (isNothing(sequence)) return []; 5798 5799 return [ sequence ]; 5800 } 5801 5802 5803 function extend(target, source) { 5804 var index, length, key, sourceKeys; 5805 5806 if (source) { 5807 sourceKeys = Object.keys(source); 5808 5809 for (index = 0, length = sourceKeys.length; index < length; index += 1) { 5810 key = sourceKeys[index]; 5811 target[key] = source[key]; 5812 } 5813 } 5814 5815 return target; 5816 } 5817 5818 5819 function repeat(string, count) { 5820 var result = '', cycle; 5821 5822 for (cycle = 0; cycle < count; cycle += 1) { 5823 result += string; 5824 } 5825 5826 return result; 5827 } 5828 5829 5830 function isNegativeZero(number) { 5831 return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number); 5832 } 5833 5834 5835 var isNothing_1 = isNothing; 5836 var isObject_1 = isObject; 5837 var toArray_1 = toArray; 5838 var repeat_1 = repeat; 5839 var isNegativeZero_1 = isNegativeZero; 5840 var extend_1 = extend; 5841 5842 var common = { 5843 isNothing: isNothing_1, 5844 isObject: isObject_1, 5845 toArray: toArray_1, 5846 repeat: repeat_1, 5847 isNegativeZero: isNegativeZero_1, 5848 extend: extend_1 5849 }; 5850 5851 // YAML error class. http://stackoverflow.com/questions/8458984 5852 5853 5854 function formatError(exception, compact) { 5855 var where = '', message = exception.reason || '(unknown reason)'; 5856 5857 if (!exception.mark) return message; 5858 5859 if (exception.mark.name) { 5860 where += 'in "' + exception.mark.name + '" '; 5861 } 5862 5863 where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')'; 5864 5865 if (!compact && exception.mark.snippet) { 5866 where += '\n\n' + exception.mark.snippet; 5867 } 5868 5869 return message + ' ' + where; 5870 } 5871 5872 5873 function YAMLException$1(reason, mark) { 5874 // Super constructor 5875 Error.call(this); 5876 5877 this.name = 'YAMLException'; 5878 this.reason = reason; 5879 this.mark = mark; 5880 this.message = formatError(this, false); 5881 5882 // Include stack trace in error object 5883 if (Error.captureStackTrace) { 5884 // Chrome and NodeJS 5885 Error.captureStackTrace(this, this.constructor); 5886 } else { 5887 // FF, IE 10+ and Safari 6+. Fallback for others 5888 this.stack = (new Error()).stack || ''; 5889 } 5890 } 5891 5892 5893 // Inherit from Error 5894 YAMLException$1.prototype = Object.create(Error.prototype); 5895 YAMLException$1.prototype.constructor = YAMLException$1; 5896 5897 5898 YAMLException$1.prototype.toString = function toString(compact) { 5899 return this.name + ': ' + formatError(this, compact); 5900 }; 5901 5902 5903 var exception = YAMLException$1; 5904 5905 // get snippet for a single line, respecting maxLength 5906 function getLine(buffer, lineStart, lineEnd, position, maxLineLength) { 5907 var head = ''; 5908 var tail = ''; 5909 var maxHalfLength = Math.floor(maxLineLength / 2) - 1; 5910 5911 if (position - lineStart > maxHalfLength) { 5912 head = ' ... '; 5913 lineStart = position - maxHalfLength + head.length; 5914 } 5915 5916 if (lineEnd - position > maxHalfLength) { 5917 tail = ' ...'; 5918 lineEnd = position + maxHalfLength - tail.length; 5919 } 5920 5921 return { 5922 str: head + buffer.slice(lineStart, lineEnd).replace(/\t/g, '→') + tail, 5923 pos: position - lineStart + head.length // relative position 5924 }; 5925 } 5926 5927 5928 function padStart(string, max) { 5929 return common.repeat(' ', max - string.length) + string; 5930 } 5931 5932 5933 function makeSnippet(mark, options) { 5934 options = Object.create(options || null); 5935 5936 if (!mark.buffer) return null; 5937 5938 if (!options.maxLength) options.maxLength = 79; 5939 if (typeof options.indent !== 'number') options.indent = 1; 5940 if (typeof options.linesBefore !== 'number') options.linesBefore = 3; 5941 if (typeof options.linesAfter !== 'number') options.linesAfter = 2; 5942 5943 var re = /\r?\n|\r|\0/g; 5944 var lineStarts = [ 0 ]; 5945 var lineEnds = []; 5946 var match; 5947 var foundLineNo = -1; 5948 5949 while ((match = re.exec(mark.buffer))) { 5950 lineEnds.push(match.index); 5951 lineStarts.push(match.index + match[0].length); 5952 5953 if (mark.position <= match.index && foundLineNo < 0) { 5954 foundLineNo = lineStarts.length - 2; 5955 } 5956 } 5957 5958 if (foundLineNo < 0) foundLineNo = lineStarts.length - 1; 5959 5960 var result = '', i, line; 5961 var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length; 5962 var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3); 5963 5964 for (i = 1; i <= options.linesBefore; i++) { 5965 if (foundLineNo - i < 0) break; 5966 line = getLine( 5967 mark.buffer, 5968 lineStarts[foundLineNo - i], 5969 lineEnds[foundLineNo - i], 5970 mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]), 5971 maxLineLength 5972 ); 5973 result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) + 5974 ' | ' + line.str + '\n' + result; 5975 } 5976 5977 line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength); 5978 result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) + 5979 ' | ' + line.str + '\n'; 5980 result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\n'; 5981 5982 for (i = 1; i <= options.linesAfter; i++) { 5983 if (foundLineNo + i >= lineEnds.length) break; 5984 line = getLine( 5985 mark.buffer, 5986 lineStarts[foundLineNo + i], 5987 lineEnds[foundLineNo + i], 5988 mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]), 5989 maxLineLength 5990 ); 5991 result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) + 5992 ' | ' + line.str + '\n'; 5993 } 5994 5995 return result.replace(/\n$/, ''); 5996 } 5997 5998 5999 var snippet = makeSnippet; 6000 6001 var TYPE_CONSTRUCTOR_OPTIONS = [ 6002 'kind', 6003 'multi', 6004 'resolve', 6005 'construct', 6006 'instanceOf', 6007 'predicate', 6008 'represent', 6009 'representName', 6010 'defaultStyle', 6011 'styleAliases' 6012 ]; 6013 6014 var YAML_NODE_KINDS = [ 6015 'scalar', 6016 'sequence', 6017 'mapping' 6018 ]; 6019 6020 function compileStyleAliases(map) { 6021 var result = {}; 6022 6023 if (map !== null) { 6024 Object.keys(map).forEach(function (style) { 6025 map[style].forEach(function (alias) { 6026 result[String(alias)] = style; 6027 }); 6028 }); 6029 } 6030 6031 return result; 6032 } 6033 6034 function Type$1(tag, options) { 6035 options = options || {}; 6036 6037 Object.keys(options).forEach(function (name) { 6038 if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) { 6039 throw new exception('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.'); 6040 } 6041 }); 6042 6043 // TODO: Add tag format check. 6044 this.options = options; // keep original options in case user wants to extend this type later 6045 this.tag = tag; 6046 this.kind = options['kind'] || null; 6047 this.resolve = options['resolve'] || function () { return true; }; 6048 this.construct = options['construct'] || function (data) { return data; }; 6049 this.instanceOf = options['instanceOf'] || null; 6050 this.predicate = options['predicate'] || null; 6051 this.represent = options['represent'] || null; 6052 this.representName = options['representName'] || null; 6053 this.defaultStyle = options['defaultStyle'] || null; 6054 this.multi = options['multi'] || false; 6055 this.styleAliases = compileStyleAliases(options['styleAliases'] || null); 6056 6057 if (YAML_NODE_KINDS.indexOf(this.kind) === -1) { 6058 throw new exception('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.'); 6059 } 6060 } 6061 6062 var type = Type$1; 6063 6064 /*eslint-disable max-len*/ 6065 6066 6067 6068 6069 6070 function compileList(schema, name) { 6071 var result = []; 6072 6073 schema[name].forEach(function (currentType) { 6074 var newIndex = result.length; 6075 6076 result.forEach(function (previousType, previousIndex) { 6077 if (previousType.tag === currentType.tag && 6078 previousType.kind === currentType.kind && 6079 previousType.multi === currentType.multi) { 6080 6081 newIndex = previousIndex; 6082 } 6083 }); 6084 6085 result[newIndex] = currentType; 6086 }); 6087 6088 return result; 6089 } 6090 6091 6092 function compileMap(/* lists... */) { 6093 var result = { 6094 scalar: {}, 6095 sequence: {}, 6096 mapping: {}, 6097 fallback: {}, 6098 multi: { 6099 scalar: [], 6100 sequence: [], 6101 mapping: [], 6102 fallback: [] 6103 } 6104 }, index, length; 6105 6106 function collectType(type) { 6107 if (type.multi) { 6108 result.multi[type.kind].push(type); 6109 result.multi['fallback'].push(type); 6110 } else { 6111 result[type.kind][type.tag] = result['fallback'][type.tag] = type; 6112 } 6113 } 6114 6115 for (index = 0, length = arguments.length; index < length; index += 1) { 6116 arguments[index].forEach(collectType); 6117 } 6118 return result; 6119 } 6120 6121 6122 function Schema$1(definition) { 6123 return this.extend(definition); 6124 } 6125 6126 6127 Schema$1.prototype.extend = function extend(definition) { 6128 var implicit = []; 6129 var explicit = []; 6130 6131 if (definition instanceof type) { 6132 // Schema.extend(type) 6133 explicit.push(definition); 6134 6135 } else if (Array.isArray(definition)) { 6136 // Schema.extend([ type1, type2, ... ]) 6137 explicit = explicit.concat(definition); 6138 6139 } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) { 6140 // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] }) 6141 if (definition.implicit) implicit = implicit.concat(definition.implicit); 6142 if (definition.explicit) explicit = explicit.concat(definition.explicit); 6143 6144 } else { 6145 throw new exception('Schema.extend argument should be a Type, [ Type ], ' + 6146 'or a schema definition ({ implicit: [...], explicit: [...] })'); 6147 } 6148 6149 implicit.forEach(function (type$1) { 6150 if (!(type$1 instanceof type)) { 6151 throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.'); 6152 } 6153 6154 if (type$1.loadKind && type$1.loadKind !== 'scalar') { 6155 throw new exception('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.'); 6156 } 6157 6158 if (type$1.multi) { 6159 throw new exception('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.'); 6160 } 6161 }); 6162 6163 explicit.forEach(function (type$1) { 6164 if (!(type$1 instanceof type)) { 6165 throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.'); 6166 } 6167 }); 6168 6169 var result = Object.create(Schema$1.prototype); 6170 6171 result.implicit = (this.implicit || []).concat(implicit); 6172 result.explicit = (this.explicit || []).concat(explicit); 6173 6174 result.compiledImplicit = compileList(result, 'implicit'); 6175 result.compiledExplicit = compileList(result, 'explicit'); 6176 result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit); 6177 6178 return result; 6179 }; 6180 6181 6182 var schema = Schema$1; 6183 6184 var str = new type('tag:yaml.org,2002:str', { 6185 kind: 'scalar', 6186 construct: function (data) { return data !== null ? data : ''; } 6187 }); 6188 6189 var seq = new type('tag:yaml.org,2002:seq', { 6190 kind: 'sequence', 6191 construct: function (data) { return data !== null ? data : []; } 6192 }); 6193 6194 var map = new type('tag:yaml.org,2002:map', { 6195 kind: 'mapping', 6196 construct: function (data) { return data !== null ? data : {}; } 6197 }); 6198 6199 var failsafe = new schema({ 6200 explicit: [ 6201 str, 6202 seq, 6203 map 6204 ] 6205 }); 6206 6207 function resolveYamlNull(data) { 6208 if (data === null) return true; 6209 6210 var max = data.length; 6211 6212 return (max === 1 && data === '~') || 6213 (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL')); 6214 } 6215 6216 function constructYamlNull() { 6217 return null; 6218 } 6219 6220 function isNull(object) { 6221 return object === null; 6222 } 6223 6224 var _null = new type('tag:yaml.org,2002:null', { 6225 kind: 'scalar', 6226 resolve: resolveYamlNull, 6227 construct: constructYamlNull, 6228 predicate: isNull, 6229 represent: { 6230 canonical: function () { return '~'; }, 6231 lowercase: function () { return 'null'; }, 6232 uppercase: function () { return 'NULL'; }, 6233 camelcase: function () { return 'Null'; }, 6234 empty: function () { return ''; } 6235 }, 6236 defaultStyle: 'lowercase' 6237 }); 6238 6239 function resolveYamlBoolean(data) { 6240 if (data === null) return false; 6241 6242 var max = data.length; 6243 6244 return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) || 6245 (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE')); 6246 } 6247 6248 function constructYamlBoolean(data) { 6249 return data === 'true' || 6250 data === 'True' || 6251 data === 'TRUE'; 6252 } 6253 6254 function isBoolean(object) { 6255 return Object.prototype.toString.call(object) === '[object Boolean]'; 6256 } 6257 6258 var bool = new type('tag:yaml.org,2002:bool', { 6259 kind: 'scalar', 6260 resolve: resolveYamlBoolean, 6261 construct: constructYamlBoolean, 6262 predicate: isBoolean, 6263 represent: { 6264 lowercase: function (object) { return object ? 'true' : 'false'; }, 6265 uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; }, 6266 camelcase: function (object) { return object ? 'True' : 'False'; } 6267 }, 6268 defaultStyle: 'lowercase' 6269 }); 6270 6271 function isHexCode(c) { 6272 return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) || 6273 ((0x41/* A */ <= c) && (c <= 0x46/* F */)) || 6274 ((0x61/* a */ <= c) && (c <= 0x66/* f */)); 6275 } 6276 6277 function isOctCode(c) { 6278 return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */)); 6279 } 6280 6281 function isDecCode(c) { 6282 return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)); 6283 } 6284 6285 function resolveYamlInteger(data) { 6286 if (data === null) return false; 6287 6288 var max = data.length, 6289 index = 0, 6290 hasDigits = false, 6291 ch; 6292 6293 if (!max) return false; 6294 6295 ch = data[index]; 6296 6297 // sign 6298 if (ch === '-' || ch === '+') { 6299 ch = data[++index]; 6300 } 6301 6302 if (ch === '0') { 6303 // 0 6304 if (index + 1 === max) return true; 6305 ch = data[++index]; 6306 6307 // base 2, base 8, base 16 6308 6309 if (ch === 'b') { 6310 // base 2 6311 index++; 6312 6313 for (; index < max; index++) { 6314 ch = data[index]; 6315 if (ch === '_') continue; 6316 if (ch !== '0' && ch !== '1') return false; 6317 hasDigits = true; 6318 } 6319 return hasDigits && ch !== '_'; 6320 } 6321 6322 6323 if (ch === 'x') { 6324 // base 16 6325 index++; 6326 6327 for (; index < max; index++) { 6328 ch = data[index]; 6329 if (ch === '_') continue; 6330 if (!isHexCode(data.charCodeAt(index))) return false; 6331 hasDigits = true; 6332 } 6333 return hasDigits && ch !== '_'; 6334 } 6335 6336 6337 if (ch === 'o') { 6338 // base 8 6339 index++; 6340 6341 for (; index < max; index++) { 6342 ch = data[index]; 6343 if (ch === '_') continue; 6344 if (!isOctCode(data.charCodeAt(index))) return false; 6345 hasDigits = true; 6346 } 6347 return hasDigits && ch !== '_'; 6348 } 6349 } 6350 6351 // base 10 (except 0) 6352 6353 // value should not start with `_`; 6354 if (ch === '_') return false; 6355 6356 for (; index < max; index++) { 6357 ch = data[index]; 6358 if (ch === '_') continue; 6359 if (!isDecCode(data.charCodeAt(index))) { 6360 return false; 6361 } 6362 hasDigits = true; 6363 } 6364 6365 // Should have digits and should not end with `_` 6366 if (!hasDigits || ch === '_') return false; 6367 6368 return true; 6369 } 6370 6371 function constructYamlInteger(data) { 6372 var value = data, sign = 1, ch; 6373 6374 if (value.indexOf('_') !== -1) { 6375 value = value.replace(/_/g, ''); 6376 } 6377 6378 ch = value[0]; 6379 6380 if (ch === '-' || ch === '+') { 6381 if (ch === '-') sign = -1; 6382 value = value.slice(1); 6383 ch = value[0]; 6384 } 6385 6386 if (value === '0') return 0; 6387 6388 if (ch === '0') { 6389 if (value[1] === 'b') return sign * parseInt(value.slice(2), 2); 6390 if (value[1] === 'x') return sign * parseInt(value.slice(2), 16); 6391 if (value[1] === 'o') return sign * parseInt(value.slice(2), 8); 6392 } 6393 6394 return sign * parseInt(value, 10); 6395 } 6396 6397 function isInteger(object) { 6398 return (Object.prototype.toString.call(object)) === '[object Number]' && 6399 (object % 1 === 0 && !common.isNegativeZero(object)); 6400 } 6401 6402 var int = new type('tag:yaml.org,2002:int', { 6403 kind: 'scalar', 6404 resolve: resolveYamlInteger, 6405 construct: constructYamlInteger, 6406 predicate: isInteger, 6407 represent: { 6408 binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); }, 6409 octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1); }, 6410 decimal: function (obj) { return obj.toString(10); }, 6411 /* eslint-disable max-len */ 6412 hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); } 6413 }, 6414 defaultStyle: 'decimal', 6415 styleAliases: { 6416 binary: [ 2, 'bin' ], 6417 octal: [ 8, 'oct' ], 6418 decimal: [ 10, 'dec' ], 6419 hexadecimal: [ 16, 'hex' ] 6420 } 6421 }); 6422 6423 var YAML_FLOAT_PATTERN = new RegExp( 6424 // 2.5e4, 2.5 and integers 6425 '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' + 6426 // .2e4, .2 6427 // special case, seems not from spec 6428 '|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' + 6429 // .inf 6430 '|[-+]?\\.(?:inf|Inf|INF)' + 6431 // .nan 6432 '|\\.(?:nan|NaN|NAN))$'); 6433 6434 function resolveYamlFloat(data) { 6435 if (data === null) return false; 6436 6437 if (!YAML_FLOAT_PATTERN.test(data) || 6438 // Quick hack to not allow integers end with `_` 6439 // Probably should update regexp & check speed 6440 data[data.length - 1] === '_') { 6441 return false; 6442 } 6443 6444 return true; 6445 } 6446 6447 function constructYamlFloat(data) { 6448 var value, sign; 6449 6450 value = data.replace(/_/g, '').toLowerCase(); 6451 sign = value[0] === '-' ? -1 : 1; 6452 6453 if ('+-'.indexOf(value[0]) >= 0) { 6454 value = value.slice(1); 6455 } 6456 6457 if (value === '.inf') { 6458 return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; 6459 6460 } else if (value === '.nan') { 6461 return NaN; 6462 } 6463 return sign * parseFloat(value, 10); 6464 } 6465 6466 6467 var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/; 6468 6469 function representYamlFloat(object, style) { 6470 var res; 6471 6472 if (isNaN(object)) { 6473 switch (style) { 6474 case 'lowercase': return '.nan'; 6475 case 'uppercase': return '.NAN'; 6476 case 'camelcase': return '.NaN'; 6477 } 6478 } else if (Number.POSITIVE_INFINITY === object) { 6479 switch (style) { 6480 case 'lowercase': return '.inf'; 6481 case 'uppercase': return '.INF'; 6482 case 'camelcase': return '.Inf'; 6483 } 6484 } else if (Number.NEGATIVE_INFINITY === object) { 6485 switch (style) { 6486 case 'lowercase': return '-.inf'; 6487 case 'uppercase': return '-.INF'; 6488 case 'camelcase': return '-.Inf'; 6489 } 6490 } else if (common.isNegativeZero(object)) { 6491 return '-0.0'; 6492 } 6493 6494 res = object.toString(10); 6495 6496 // JS stringifier can build scientific format without dots: 5e-100, 6497 // while YAML requres dot: 5.e-100. Fix it with simple hack 6498 6499 return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res; 6500 } 6501 6502 function isFloat(object) { 6503 return (Object.prototype.toString.call(object) === '[object Number]') && 6504 (object % 1 !== 0 || common.isNegativeZero(object)); 6505 } 6506 6507 var float = new type('tag:yaml.org,2002:float', { 6508 kind: 'scalar', 6509 resolve: resolveYamlFloat, 6510 construct: constructYamlFloat, 6511 predicate: isFloat, 6512 represent: representYamlFloat, 6513 defaultStyle: 'lowercase' 6514 }); 6515 6516 var json = failsafe.extend({ 6517 implicit: [ 6518 _null, 6519 bool, 6520 int, 6521 float 6522 ] 6523 }); 6524 6525 var core = json; 6526 6527 var YAML_DATE_REGEXP = new RegExp( 6528 '^([0-9][0-9][0-9][0-9])' + // [1] year 6529 '-([0-9][0-9])' + // [2] month 6530 '-([0-9][0-9])$'); // [3] day 6531 6532 var YAML_TIMESTAMP_REGEXP = new RegExp( 6533 '^([0-9][0-9][0-9][0-9])' + // [1] year 6534 '-([0-9][0-9]?)' + // [2] month 6535 '-([0-9][0-9]?)' + // [3] day 6536 '(?:[Tt]|[ \\t]+)' + // ... 6537 '([0-9][0-9]?)' + // [4] hour 6538 ':([0-9][0-9])' + // [5] minute 6539 ':([0-9][0-9])' + // [6] second 6540 '(?:\\.([0-9]*))?' + // [7] fraction 6541 '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour 6542 '(?::([0-9][0-9]))?))?$'); // [11] tz_minute 6543 6544 function resolveYamlTimestamp(data) { 6545 if (data === null) return false; 6546 if (YAML_DATE_REGEXP.exec(data) !== null) return true; 6547 if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true; 6548 return false; 6549 } 6550 6551 function constructYamlTimestamp(data) { 6552 var match, year, month, day, hour, minute, second, fraction = 0, 6553 delta = null, tz_hour, tz_minute, date; 6554 6555 match = YAML_DATE_REGEXP.exec(data); 6556 if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data); 6557 6558 if (match === null) throw new Error('Date resolve error'); 6559 6560 // match: [1] year [2] month [3] day 6561 6562 year = +(match[1]); 6563 month = +(match[2]) - 1; // JS month starts with 0 6564 day = +(match[3]); 6565 6566 if (!match[4]) { // no hour 6567 return new Date(Date.UTC(year, month, day)); 6568 } 6569 6570 // match: [4] hour [5] minute [6] second [7] fraction 6571 6572 hour = +(match[4]); 6573 minute = +(match[5]); 6574 second = +(match[6]); 6575 6576 if (match[7]) { 6577 fraction = match[7].slice(0, 3); 6578 while (fraction.length < 3) { // milli-seconds 6579 fraction += '0'; 6580 } 6581 fraction = +fraction; 6582 } 6583 6584 // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute 6585 6586 if (match[9]) { 6587 tz_hour = +(match[10]); 6588 tz_minute = +(match[11] || 0); 6589 delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds 6590 if (match[9] === '-') delta = -delta; 6591 } 6592 6593 date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction)); 6594 6595 if (delta) date.setTime(date.getTime() - delta); 6596 6597 return date; 6598 } 6599 6600 function representYamlTimestamp(object /*, style*/) { 6601 return object.toISOString(); 6602 } 6603 6604 var timestamp = new type('tag:yaml.org,2002:timestamp', { 6605 kind: 'scalar', 6606 resolve: resolveYamlTimestamp, 6607 construct: constructYamlTimestamp, 6608 instanceOf: Date, 6609 represent: representYamlTimestamp 6610 }); 6611 6612 function resolveYamlMerge(data) { 6613 return data === '<<' || data === null; 6614 } 6615 6616 var merge = new type('tag:yaml.org,2002:merge', { 6617 kind: 'scalar', 6618 resolve: resolveYamlMerge 6619 }); 6620 6621 /*eslint-disable no-bitwise*/ 6622 6623 6624 6625 6626 6627 // [ 64, 65, 66 ] -> [ padding, CR, LF ] 6628 var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r'; 6629 6630 6631 function resolveYamlBinary(data) { 6632 if (data === null) return false; 6633 6634 var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP; 6635 6636 // Convert one by one. 6637 for (idx = 0; idx < max; idx++) { 6638 code = map.indexOf(data.charAt(idx)); 6639 6640 // Skip CR/LF 6641 if (code > 64) continue; 6642 6643 // Fail on illegal characters 6644 if (code < 0) return false; 6645 6646 bitlen += 6; 6647 } 6648 6649 // If there are any bits left, source was corrupted 6650 return (bitlen % 8) === 0; 6651 } 6652 6653 function constructYamlBinary(data) { 6654 var idx, tailbits, 6655 input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan 6656 max = input.length, 6657 map = BASE64_MAP, 6658 bits = 0, 6659 result = []; 6660 6661 // Collect by 6*4 bits (3 bytes) 6662 6663 for (idx = 0; idx < max; idx++) { 6664 if ((idx % 4 === 0) && idx) { 6665 result.push((bits >> 16) & 0xFF); 6666 result.push((bits >> 8) & 0xFF); 6667 result.push(bits & 0xFF); 6668 } 6669 6670 bits = (bits << 6) | map.indexOf(input.charAt(idx)); 6671 } 6672 6673 // Dump tail 6674 6675 tailbits = (max % 4) * 6; 6676 6677 if (tailbits === 0) { 6678 result.push((bits >> 16) & 0xFF); 6679 result.push((bits >> 8) & 0xFF); 6680 result.push(bits & 0xFF); 6681 } else if (tailbits === 18) { 6682 result.push((bits >> 10) & 0xFF); 6683 result.push((bits >> 2) & 0xFF); 6684 } else if (tailbits === 12) { 6685 result.push((bits >> 4) & 0xFF); 6686 } 6687 6688 return new Uint8Array(result); 6689 } 6690 6691 function representYamlBinary(object /*, style*/) { 6692 var result = '', bits = 0, idx, tail, 6693 max = object.length, 6694 map = BASE64_MAP; 6695 6696 // Convert every three bytes to 4 ASCII characters. 6697 6698 for (idx = 0; idx < max; idx++) { 6699 if ((idx % 3 === 0) && idx) { 6700 result += map[(bits >> 18) & 0x3F]; 6701 result += map[(bits >> 12) & 0x3F]; 6702 result += map[(bits >> 6) & 0x3F]; 6703 result += map[bits & 0x3F]; 6704 } 6705 6706 bits = (bits << 8) + object[idx]; 6707 } 6708 6709 // Dump tail 6710 6711 tail = max % 3; 6712 6713 if (tail === 0) { 6714 result += map[(bits >> 18) & 0x3F]; 6715 result += map[(bits >> 12) & 0x3F]; 6716 result += map[(bits >> 6) & 0x3F]; 6717 result += map[bits & 0x3F]; 6718 } else if (tail === 2) { 6719 result += map[(bits >> 10) & 0x3F]; 6720 result += map[(bits >> 4) & 0x3F]; 6721 result += map[(bits << 2) & 0x3F]; 6722 result += map[64]; 6723 } else if (tail === 1) { 6724 result += map[(bits >> 2) & 0x3F]; 6725 result += map[(bits << 4) & 0x3F]; 6726 result += map[64]; 6727 result += map[64]; 6728 } 6729 6730 return result; 6731 } 6732 6733 function isBinary(obj) { 6734 return Object.prototype.toString.call(obj) === '[object Uint8Array]'; 6735 } 6736 6737 var binary = new type('tag:yaml.org,2002:binary', { 6738 kind: 'scalar', 6739 resolve: resolveYamlBinary, 6740 construct: constructYamlBinary, 6741 predicate: isBinary, 6742 represent: representYamlBinary 6743 }); 6744 6745 var _hasOwnProperty$3 = Object.prototype.hasOwnProperty; 6746 var _toString$2 = Object.prototype.toString; 6747 6748 function resolveYamlOmap(data) { 6749 if (data === null) return true; 6750 6751 var objectKeys = [], index, length, pair, pairKey, pairHasKey, 6752 object = data; 6753 6754 for (index = 0, length = object.length; index < length; index += 1) { 6755 pair = object[index]; 6756 pairHasKey = false; 6757 6758 if (_toString$2.call(pair) !== '[object Object]') return false; 6759 6760 for (pairKey in pair) { 6761 if (_hasOwnProperty$3.call(pair, pairKey)) { 6762 if (!pairHasKey) pairHasKey = true; 6763 else return false; 6764 } 6765 } 6766 6767 if (!pairHasKey) return false; 6768 6769 if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey); 6770 else return false; 6771 } 6772 6773 return true; 6774 } 6775 6776 function constructYamlOmap(data) { 6777 return data !== null ? data : []; 6778 } 6779 6780 var omap = new type('tag:yaml.org,2002:omap', { 6781 kind: 'sequence', 6782 resolve: resolveYamlOmap, 6783 construct: constructYamlOmap 6784 }); 6785 6786 var _toString$1 = Object.prototype.toString; 6787 6788 function resolveYamlPairs(data) { 6789 if (data === null) return true; 6790 6791 var index, length, pair, keys, result, 6792 object = data; 6793 6794 result = new Array(object.length); 6795 6796 for (index = 0, length = object.length; index < length; index += 1) { 6797 pair = object[index]; 6798 6799 if (_toString$1.call(pair) !== '[object Object]') return false; 6800 6801 keys = Object.keys(pair); 6802 6803 if (keys.length !== 1) return false; 6804 6805 result[index] = [ keys[0], pair[keys[0]] ]; 6806 } 6807 6808 return true; 6809 } 6810 6811 function constructYamlPairs(data) { 6812 if (data === null) return []; 6813 6814 var index, length, pair, keys, result, 6815 object = data; 6816 6817 result = new Array(object.length); 6818 6819 for (index = 0, length = object.length; index < length; index += 1) { 6820 pair = object[index]; 6821 6822 keys = Object.keys(pair); 6823 6824 result[index] = [ keys[0], pair[keys[0]] ]; 6825 } 6826 6827 return result; 6828 } 6829 6830 var pairs = new type('tag:yaml.org,2002:pairs', { 6831 kind: 'sequence', 6832 resolve: resolveYamlPairs, 6833 construct: constructYamlPairs 6834 }); 6835 6836 var _hasOwnProperty$2 = Object.prototype.hasOwnProperty; 6837 6838 function resolveYamlSet(data) { 6839 if (data === null) return true; 6840 6841 var key, object = data; 6842 6843 for (key in object) { 6844 if (_hasOwnProperty$2.call(object, key)) { 6845 if (object[key] !== null) return false; 6846 } 6847 } 6848 6849 return true; 6850 } 6851 6852 function constructYamlSet(data) { 6853 return data !== null ? data : {}; 6854 } 6855 6856 var set = new type('tag:yaml.org,2002:set', { 6857 kind: 'mapping', 6858 resolve: resolveYamlSet, 6859 construct: constructYamlSet 6860 }); 6861 6862 var _default = core.extend({ 6863 implicit: [ 6864 timestamp, 6865 merge 6866 ], 6867 explicit: [ 6868 binary, 6869 omap, 6870 pairs, 6871 set 6872 ] 6873 }); 6874 6875 /*eslint-disable max-len,no-use-before-define*/ 6876 6877 6878 6879 6880 6881 6882 6883 var _hasOwnProperty$1 = Object.prototype.hasOwnProperty; 6884 6885 6886 var CONTEXT_FLOW_IN = 1; 6887 var CONTEXT_FLOW_OUT = 2; 6888 var CONTEXT_BLOCK_IN = 3; 6889 var CONTEXT_BLOCK_OUT = 4; 6890 6891 6892 var CHOMPING_CLIP = 1; 6893 var CHOMPING_STRIP = 2; 6894 var CHOMPING_KEEP = 3; 6895 6896 6897 var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; 6898 var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/; 6899 var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/; 6900 var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i; 6901 var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; 6902 6903 6904 function _class(obj) { return Object.prototype.toString.call(obj); } 6905 6906 function is_EOL(c) { 6907 return (c === 0x0A/* LF */) || (c === 0x0D/* CR */); 6908 } 6909 6910 function is_WHITE_SPACE(c) { 6911 return (c === 0x09/* Tab */) || (c === 0x20/* Space */); 6912 } 6913 6914 function is_WS_OR_EOL(c) { 6915 return (c === 0x09/* Tab */) || 6916 (c === 0x20/* Space */) || 6917 (c === 0x0A/* LF */) || 6918 (c === 0x0D/* CR */); 6919 } 6920 6921 function is_FLOW_INDICATOR(c) { 6922 return c === 0x2C/* , */ || 6923 c === 0x5B/* [ */ || 6924 c === 0x5D/* ] */ || 6925 c === 0x7B/* { */ || 6926 c === 0x7D/* } */; 6927 } 6928 6929 function fromHexCode(c) { 6930 var lc; 6931 6932 if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { 6933 return c - 0x30; 6934 } 6935 6936 /*eslint-disable no-bitwise*/ 6937 lc = c | 0x20; 6938 6939 if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) { 6940 return lc - 0x61 + 10; 6941 } 6942 6943 return -1; 6944 } 6945 6946 function escapedHexLen(c) { 6947 if (c === 0x78/* x */) { return 2; } 6948 if (c === 0x75/* u */) { return 4; } 6949 if (c === 0x55/* U */) { return 8; } 6950 return 0; 6951 } 6952 6953 function fromDecimalCode(c) { 6954 if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { 6955 return c - 0x30; 6956 } 6957 6958 return -1; 6959 } 6960 6961 function simpleEscapeSequence(c) { 6962 /* eslint-disable indent */ 6963 return (c === 0x30/* 0 */) ? '\x00' : 6964 (c === 0x61/* a */) ? '\x07' : 6965 (c === 0x62/* b */) ? '\x08' : 6966 (c === 0x74/* t */) ? '\x09' : 6967 (c === 0x09/* Tab */) ? '\x09' : 6968 (c === 0x6E/* n */) ? '\x0A' : 6969 (c === 0x76/* v */) ? '\x0B' : 6970 (c === 0x66/* f */) ? '\x0C' : 6971 (c === 0x72/* r */) ? '\x0D' : 6972 (c === 0x65/* e */) ? '\x1B' : 6973 (c === 0x20/* Space */) ? ' ' : 6974 (c === 0x22/* " */) ? '\x22' : 6975 (c === 0x2F/* / */) ? '/' : 6976 (c === 0x5C/* \ */) ? '\x5C' : 6977 (c === 0x4E/* N */) ? '\x85' : 6978 (c === 0x5F/* _ */) ? '\xA0' : 6979 (c === 0x4C/* L */) ? '\u2028' : 6980 (c === 0x50/* P */) ? '\u2029' : ''; 6981 } 6982 6983 function charFromCodepoint(c) { 6984 if (c <= 0xFFFF) { 6985 return String.fromCharCode(c); 6986 } 6987 // Encode UTF-16 surrogate pair 6988 // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF 6989 return String.fromCharCode( 6990 ((c - 0x010000) >> 10) + 0xD800, 6991 ((c - 0x010000) & 0x03FF) + 0xDC00 6992 ); 6993 } 6994 6995 var simpleEscapeCheck = new Array(256); // integer, for fast access 6996 var simpleEscapeMap = new Array(256); 6997 for (var i = 0; i < 256; i++) { 6998 simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0; 6999 simpleEscapeMap[i] = simpleEscapeSequence(i); 7000 } 7001 7002 7003 function State$1(input, options) { 7004 this.input = input; 7005 7006 this.filename = options['filename'] || null; 7007 this.schema = options['schema'] || _default; 7008 this.onWarning = options['onWarning'] || null; 7009 // (Hidden) Remove? makes the loader to expect YAML 1.1 documents 7010 // if such documents have no explicit %YAML directive 7011 this.legacy = options['legacy'] || false; 7012 7013 this.json = options['json'] || false; 7014 this.listener = options['listener'] || null; 7015 7016 this.implicitTypes = this.schema.compiledImplicit; 7017 this.typeMap = this.schema.compiledTypeMap; 7018 7019 this.length = input.length; 7020 this.position = 0; 7021 this.line = 0; 7022 this.lineStart = 0; 7023 this.lineIndent = 0; 7024 7025 // position of first leading tab in the current line, 7026 // used to make sure there are no tabs in the indentation 7027 this.firstTabInLine = -1; 7028 7029 this.documents = []; 7030 7031 /* 7032 this.version; 7033 this.checkLineBreaks; 7034 this.tagMap; 7035 this.anchorMap; 7036 this.tag; 7037 this.anchor; 7038 this.kind; 7039 this.result;*/ 7040 7041 } 7042 7043 7044 function generateError(state, message) { 7045 var mark = { 7046 name: state.filename, 7047 buffer: state.input.slice(0, -1), // omit trailing \0 7048 position: state.position, 7049 line: state.line, 7050 column: state.position - state.lineStart 7051 }; 7052 7053 mark.snippet = snippet(mark); 7054 7055 return new exception(message, mark); 7056 } 7057 7058 function throwError(state, message) { 7059 throw generateError(state, message); 7060 } 7061 7062 function throwWarning(state, message) { 7063 if (state.onWarning) { 7064 state.onWarning.call(null, generateError(state, message)); 7065 } 7066 } 7067 7068 7069 var directiveHandlers = { 7070 7071 YAML: function handleYamlDirective(state, name, args) { 7072 7073 var match, major, minor; 7074 7075 if (state.version !== null) { 7076 throwError(state, 'duplication of %YAML directive'); 7077 } 7078 7079 if (args.length !== 1) { 7080 throwError(state, 'YAML directive accepts exactly one argument'); 7081 } 7082 7083 match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]); 7084 7085 if (match === null) { 7086 throwError(state, 'ill-formed argument of the YAML directive'); 7087 } 7088 7089 major = parseInt(match[1], 10); 7090 minor = parseInt(match[2], 10); 7091 7092 if (major !== 1) { 7093 throwError(state, 'unacceptable YAML version of the document'); 7094 } 7095 7096 state.version = args[0]; 7097 state.checkLineBreaks = (minor < 2); 7098 7099 if (minor !== 1 && minor !== 2) { 7100 throwWarning(state, 'unsupported YAML version of the document'); 7101 } 7102 }, 7103 7104 TAG: function handleTagDirective(state, name, args) { 7105 7106 var handle, prefix; 7107 7108 if (args.length !== 2) { 7109 throwError(state, 'TAG directive accepts exactly two arguments'); 7110 } 7111 7112 handle = args[0]; 7113 prefix = args[1]; 7114 7115 if (!PATTERN_TAG_HANDLE.test(handle)) { 7116 throwError(state, 'ill-formed tag handle (first argument) of the TAG directive'); 7117 } 7118 7119 if (_hasOwnProperty$1.call(state.tagMap, handle)) { 7120 throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle'); 7121 } 7122 7123 if (!PATTERN_TAG_URI.test(prefix)) { 7124 throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive'); 7125 } 7126 7127 try { 7128 prefix = decodeURIComponent(prefix); 7129 } catch (err) { 7130 throwError(state, 'tag prefix is malformed: ' + prefix); 7131 } 7132 7133 state.tagMap[handle] = prefix; 7134 } 7135 }; 7136 7137 7138 function captureSegment(state, start, end, checkJson) { 7139 var _position, _length, _character, _result; 7140 7141 if (start < end) { 7142 _result = state.input.slice(start, end); 7143 7144 if (checkJson) { 7145 for (_position = 0, _length = _result.length; _position < _length; _position += 1) { 7146 _character = _result.charCodeAt(_position); 7147 if (!(_character === 0x09 || 7148 (0x20 <= _character && _character <= 0x10FFFF))) { 7149 throwError(state, 'expected valid JSON character'); 7150 } 7151 } 7152 } else if (PATTERN_NON_PRINTABLE.test(_result)) { 7153 throwError(state, 'the stream contains non-printable characters'); 7154 } 7155 7156 state.result += _result; 7157 } 7158 } 7159 7160 function mergeMappings(state, destination, source, overridableKeys) { 7161 var sourceKeys, key, index, quantity; 7162 7163 if (!common.isObject(source)) { 7164 throwError(state, 'cannot merge mappings; the provided source object is unacceptable'); 7165 } 7166 7167 sourceKeys = Object.keys(source); 7168 7169 for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) { 7170 key = sourceKeys[index]; 7171 7172 if (!_hasOwnProperty$1.call(destination, key)) { 7173 destination[key] = source[key]; 7174 overridableKeys[key] = true; 7175 } 7176 } 7177 } 7178 7179 function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, 7180 startLine, startLineStart, startPos) { 7181 7182 var index, quantity; 7183 7184 // The output is a plain object here, so keys can only be strings. 7185 // We need to convert keyNode to a string, but doing so can hang the process 7186 // (deeply nested arrays that explode exponentially using aliases). 7187 if (Array.isArray(keyNode)) { 7188 keyNode = Array.prototype.slice.call(keyNode); 7189 7190 for (index = 0, quantity = keyNode.length; index < quantity; index += 1) { 7191 if (Array.isArray(keyNode[index])) { 7192 throwError(state, 'nested arrays are not supported inside keys'); 7193 } 7194 7195 if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') { 7196 keyNode[index] = '[object Object]'; 7197 } 7198 } 7199 } 7200 7201 // Avoid code execution in load() via toString property 7202 // (still use its own toString for arrays, timestamps, 7203 // and whatever user schema extensions happen to have @@toStringTag) 7204 if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') { 7205 keyNode = '[object Object]'; 7206 } 7207 7208 7209 keyNode = String(keyNode); 7210 7211 if (_result === null) { 7212 _result = {}; 7213 } 7214 7215 if (keyTag === 'tag:yaml.org,2002:merge') { 7216 if (Array.isArray(valueNode)) { 7217 for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { 7218 mergeMappings(state, _result, valueNode[index], overridableKeys); 7219 } 7220 } else { 7221 mergeMappings(state, _result, valueNode, overridableKeys); 7222 } 7223 } else { 7224 if (!state.json && 7225 !_hasOwnProperty$1.call(overridableKeys, keyNode) && 7226 _hasOwnProperty$1.call(_result, keyNode)) { 7227 state.line = startLine || state.line; 7228 state.lineStart = startLineStart || state.lineStart; 7229 state.position = startPos || state.position; 7230 throwError(state, 'duplicated mapping key'); 7231 } 7232 7233 // used for this specific key only because Object.defineProperty is slow 7234 if (keyNode === '__proto__') { 7235 Object.defineProperty(_result, keyNode, { 7236 configurable: true, 7237 enumerable: true, 7238 writable: true, 7239 value: valueNode 7240 }); 7241 } else { 7242 _result[keyNode] = valueNode; 7243 } 7244 delete overridableKeys[keyNode]; 7245 } 7246 7247 return _result; 7248 } 7249 7250 function readLineBreak(state) { 7251 var ch; 7252 7253 ch = state.input.charCodeAt(state.position); 7254 7255 if (ch === 0x0A/* LF */) { 7256 state.position++; 7257 } else if (ch === 0x0D/* CR */) { 7258 state.position++; 7259 if (state.input.charCodeAt(state.position) === 0x0A/* LF */) { 7260 state.position++; 7261 } 7262 } else { 7263 throwError(state, 'a line break is expected'); 7264 } 7265 7266 state.line += 1; 7267 state.lineStart = state.position; 7268 state.firstTabInLine = -1; 7269 } 7270 7271 function skipSeparationSpace(state, allowComments, checkIndent) { 7272 var lineBreaks = 0, 7273 ch = state.input.charCodeAt(state.position); 7274 7275 while (ch !== 0) { 7276 while (is_WHITE_SPACE(ch)) { 7277 if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) { 7278 state.firstTabInLine = state.position; 7279 } 7280 ch = state.input.charCodeAt(++state.position); 7281 } 7282 7283 if (allowComments && ch === 0x23/* # */) { 7284 do { 7285 ch = state.input.charCodeAt(++state.position); 7286 } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0); 7287 } 7288 7289 if (is_EOL(ch)) { 7290 readLineBreak(state); 7291 7292 ch = state.input.charCodeAt(state.position); 7293 lineBreaks++; 7294 state.lineIndent = 0; 7295 7296 while (ch === 0x20/* Space */) { 7297 state.lineIndent++; 7298 ch = state.input.charCodeAt(++state.position); 7299 } 7300 } else { 7301 break; 7302 } 7303 } 7304 7305 if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) { 7306 throwWarning(state, 'deficient indentation'); 7307 } 7308 7309 return lineBreaks; 7310 } 7311 7312 function testDocumentSeparator(state) { 7313 var _position = state.position, 7314 ch; 7315 7316 ch = state.input.charCodeAt(_position); 7317 7318 // Condition state.position === state.lineStart is tested 7319 // in parent on each call, for efficiency. No needs to test here again. 7320 if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) && 7321 ch === state.input.charCodeAt(_position + 1) && 7322 ch === state.input.charCodeAt(_position + 2)) { 7323 7324 _position += 3; 7325 7326 ch = state.input.charCodeAt(_position); 7327 7328 if (ch === 0 || is_WS_OR_EOL(ch)) { 7329 return true; 7330 } 7331 } 7332 7333 return false; 7334 } 7335 7336 function writeFoldedLines(state, count) { 7337 if (count === 1) { 7338 state.result += ' '; 7339 } else if (count > 1) { 7340 state.result += common.repeat('\n', count - 1); 7341 } 7342 } 7343 7344 7345 function readPlainScalar(state, nodeIndent, withinFlowCollection) { 7346 var preceding, 7347 following, 7348 captureStart, 7349 captureEnd, 7350 hasPendingContent, 7351 _line, 7352 _lineStart, 7353 _lineIndent, 7354 _kind = state.kind, 7355 _result = state.result, 7356 ch; 7357 7358 ch = state.input.charCodeAt(state.position); 7359 7360 if (is_WS_OR_EOL(ch) || 7361 is_FLOW_INDICATOR(ch) || 7362 ch === 0x23/* # */ || 7363 ch === 0x26/* & */ || 7364 ch === 0x2A/* * */ || 7365 ch === 0x21/* ! */ || 7366 ch === 0x7C/* | */ || 7367 ch === 0x3E/* > */ || 7368 ch === 0x27/* ' */ || 7369 ch === 0x22/* " */ || 7370 ch === 0x25/* % */ || 7371 ch === 0x40/* @ */ || 7372 ch === 0x60/* ` */) { 7373 return false; 7374 } 7375 7376 if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) { 7377 following = state.input.charCodeAt(state.position + 1); 7378 7379 if (is_WS_OR_EOL(following) || 7380 withinFlowCollection && is_FLOW_INDICATOR(following)) { 7381 return false; 7382 } 7383 } 7384 7385 state.kind = 'scalar'; 7386 state.result = ''; 7387 captureStart = captureEnd = state.position; 7388 hasPendingContent = false; 7389 7390 while (ch !== 0) { 7391 if (ch === 0x3A/* : */) { 7392 following = state.input.charCodeAt(state.position + 1); 7393 7394 if (is_WS_OR_EOL(following) || 7395 withinFlowCollection && is_FLOW_INDICATOR(following)) { 7396 break; 7397 } 7398 7399 } else if (ch === 0x23/* # */) { 7400 preceding = state.input.charCodeAt(state.position - 1); 7401 7402 if (is_WS_OR_EOL(preceding)) { 7403 break; 7404 } 7405 7406 } else if ((state.position === state.lineStart && testDocumentSeparator(state)) || 7407 withinFlowCollection && is_FLOW_INDICATOR(ch)) { 7408 break; 7409 7410 } else if (is_EOL(ch)) { 7411 _line = state.line; 7412 _lineStart = state.lineStart; 7413 _lineIndent = state.lineIndent; 7414 skipSeparationSpace(state, false, -1); 7415 7416 if (state.lineIndent >= nodeIndent) { 7417 hasPendingContent = true; 7418 ch = state.input.charCodeAt(state.position); 7419 continue; 7420 } else { 7421 state.position = captureEnd; 7422 state.line = _line; 7423 state.lineStart = _lineStart; 7424 state.lineIndent = _lineIndent; 7425 break; 7426 } 7427 } 7428 7429 if (hasPendingContent) { 7430 captureSegment(state, captureStart, captureEnd, false); 7431 writeFoldedLines(state, state.line - _line); 7432 captureStart = captureEnd = state.position; 7433 hasPendingContent = false; 7434 } 7435 7436 if (!is_WHITE_SPACE(ch)) { 7437 captureEnd = state.position + 1; 7438 } 7439 7440 ch = state.input.charCodeAt(++state.position); 7441 } 7442 7443 captureSegment(state, captureStart, captureEnd, false); 7444 7445 if (state.result) { 7446 return true; 7447 } 7448 7449 state.kind = _kind; 7450 state.result = _result; 7451 return false; 7452 } 7453 7454 function readSingleQuotedScalar(state, nodeIndent) { 7455 var ch, 7456 captureStart, captureEnd; 7457 7458 ch = state.input.charCodeAt(state.position); 7459 7460 if (ch !== 0x27/* ' */) { 7461 return false; 7462 } 7463 7464 state.kind = 'scalar'; 7465 state.result = ''; 7466 state.position++; 7467 captureStart = captureEnd = state.position; 7468 7469 while ((ch = state.input.charCodeAt(state.position)) !== 0) { 7470 if (ch === 0x27/* ' */) { 7471 captureSegment(state, captureStart, state.position, true); 7472 ch = state.input.charCodeAt(++state.position); 7473 7474 if (ch === 0x27/* ' */) { 7475 captureStart = state.position; 7476 state.position++; 7477 captureEnd = state.position; 7478 } else { 7479 return true; 7480 } 7481 7482 } else if (is_EOL(ch)) { 7483 captureSegment(state, captureStart, captureEnd, true); 7484 writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); 7485 captureStart = captureEnd = state.position; 7486 7487 } else if (state.position === state.lineStart && testDocumentSeparator(state)) { 7488 throwError(state, 'unexpected end of the document within a single quoted scalar'); 7489 7490 } else { 7491 state.position++; 7492 captureEnd = state.position; 7493 } 7494 } 7495 7496 throwError(state, 'unexpected end of the stream within a single quoted scalar'); 7497 } 7498 7499 function readDoubleQuotedScalar(state, nodeIndent) { 7500 var captureStart, 7501 captureEnd, 7502 hexLength, 7503 hexResult, 7504 tmp, 7505 ch; 7506 7507 ch = state.input.charCodeAt(state.position); 7508 7509 if (ch !== 0x22/* " */) { 7510 return false; 7511 } 7512 7513 state.kind = 'scalar'; 7514 state.result = ''; 7515 state.position++; 7516 captureStart = captureEnd = state.position; 7517 7518 while ((ch = state.input.charCodeAt(state.position)) !== 0) { 7519 if (ch === 0x22/* " */) { 7520 captureSegment(state, captureStart, state.position, true); 7521 state.position++; 7522 return true; 7523 7524 } else if (ch === 0x5C/* \ */) { 7525 captureSegment(state, captureStart, state.position, true); 7526 ch = state.input.charCodeAt(++state.position); 7527 7528 if (is_EOL(ch)) { 7529 skipSeparationSpace(state, false, nodeIndent); 7530 7531 // TODO: rework to inline fn with no type cast? 7532 } else if (ch < 256 && simpleEscapeCheck[ch]) { 7533 state.result += simpleEscapeMap[ch]; 7534 state.position++; 7535 7536 } else if ((tmp = escapedHexLen(ch)) > 0) { 7537 hexLength = tmp; 7538 hexResult = 0; 7539 7540 for (; hexLength > 0; hexLength--) { 7541 ch = state.input.charCodeAt(++state.position); 7542 7543 if ((tmp = fromHexCode(ch)) >= 0) { 7544 hexResult = (hexResult << 4) + tmp; 7545 7546 } else { 7547 throwError(state, 'expected hexadecimal character'); 7548 } 7549 } 7550 7551 state.result += charFromCodepoint(hexResult); 7552 7553 state.position++; 7554 7555 } else { 7556 throwError(state, 'unknown escape sequence'); 7557 } 7558 7559 captureStart = captureEnd = state.position; 7560 7561 } else if (is_EOL(ch)) { 7562 captureSegment(state, captureStart, captureEnd, true); 7563 writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); 7564 captureStart = captureEnd = state.position; 7565 7566 } else if (state.position === state.lineStart && testDocumentSeparator(state)) { 7567 throwError(state, 'unexpected end of the document within a double quoted scalar'); 7568 7569 } else { 7570 state.position++; 7571 captureEnd = state.position; 7572 } 7573 } 7574 7575 throwError(state, 'unexpected end of the stream within a double quoted scalar'); 7576 } 7577 7578 function readFlowCollection(state, nodeIndent) { 7579 var readNext = true, 7580 _line, 7581 _lineStart, 7582 _pos, 7583 _tag = state.tag, 7584 _result, 7585 _anchor = state.anchor, 7586 following, 7587 terminator, 7588 isPair, 7589 isExplicitPair, 7590 isMapping, 7591 overridableKeys = Object.create(null), 7592 keyNode, 7593 keyTag, 7594 valueNode, 7595 ch; 7596 7597 ch = state.input.charCodeAt(state.position); 7598 7599 if (ch === 0x5B/* [ */) { 7600 terminator = 0x5D;/* ] */ 7601 isMapping = false; 7602 _result = []; 7603 } else if (ch === 0x7B/* { */) { 7604 terminator = 0x7D;/* } */ 7605 isMapping = true; 7606 _result = {}; 7607 } else { 7608 return false; 7609 } 7610 7611 if (state.anchor !== null) { 7612 state.anchorMap[state.anchor] = _result; 7613 } 7614 7615 ch = state.input.charCodeAt(++state.position); 7616 7617 while (ch !== 0) { 7618 skipSeparationSpace(state, true, nodeIndent); 7619 7620 ch = state.input.charCodeAt(state.position); 7621 7622 if (ch === terminator) { 7623 state.position++; 7624 state.tag = _tag; 7625 state.anchor = _anchor; 7626 state.kind = isMapping ? 'mapping' : 'sequence'; 7627 state.result = _result; 7628 return true; 7629 } else if (!readNext) { 7630 throwError(state, 'missed comma between flow collection entries'); 7631 } else if (ch === 0x2C/* , */) { 7632 // "flow collection entries can never be completely empty", as per YAML 1.2, section 7.4 7633 throwError(state, "expected the node content, but found ','"); 7634 } 7635 7636 keyTag = keyNode = valueNode = null; 7637 isPair = isExplicitPair = false; 7638 7639 if (ch === 0x3F/* ? */) { 7640 following = state.input.charCodeAt(state.position + 1); 7641 7642 if (is_WS_OR_EOL(following)) { 7643 isPair = isExplicitPair = true; 7644 state.position++; 7645 skipSeparationSpace(state, true, nodeIndent); 7646 } 7647 } 7648 7649 _line = state.line; // Save the current line. 7650 _lineStart = state.lineStart; 7651 _pos = state.position; 7652 composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); 7653 keyTag = state.tag; 7654 keyNode = state.result; 7655 skipSeparationSpace(state, true, nodeIndent); 7656 7657 ch = state.input.charCodeAt(state.position); 7658 7659 if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) { 7660 isPair = true; 7661 ch = state.input.charCodeAt(++state.position); 7662 skipSeparationSpace(state, true, nodeIndent); 7663 composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); 7664 valueNode = state.result; 7665 } 7666 7667 if (isMapping) { 7668 storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos); 7669 } else if (isPair) { 7670 _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos)); 7671 } else { 7672 _result.push(keyNode); 7673 } 7674 7675 skipSeparationSpace(state, true, nodeIndent); 7676 7677 ch = state.input.charCodeAt(state.position); 7678 7679 if (ch === 0x2C/* , */) { 7680 readNext = true; 7681 ch = state.input.charCodeAt(++state.position); 7682 } else { 7683 readNext = false; 7684 } 7685 } 7686 7687 throwError(state, 'unexpected end of the stream within a flow collection'); 7688 } 7689 7690 function readBlockScalar(state, nodeIndent) { 7691 var captureStart, 7692 folding, 7693 chomping = CHOMPING_CLIP, 7694 didReadContent = false, 7695 detectedIndent = false, 7696 textIndent = nodeIndent, 7697 emptyLines = 0, 7698 atMoreIndented = false, 7699 tmp, 7700 ch; 7701 7702 ch = state.input.charCodeAt(state.position); 7703 7704 if (ch === 0x7C/* | */) { 7705 folding = false; 7706 } else if (ch === 0x3E/* > */) { 7707 folding = true; 7708 } else { 7709 return false; 7710 } 7711 7712 state.kind = 'scalar'; 7713 state.result = ''; 7714 7715 while (ch !== 0) { 7716 ch = state.input.charCodeAt(++state.position); 7717 7718 if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { 7719 if (CHOMPING_CLIP === chomping) { 7720 chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP; 7721 } else { 7722 throwError(state, 'repeat of a chomping mode identifier'); 7723 } 7724 7725 } else if ((tmp = fromDecimalCode(ch)) >= 0) { 7726 if (tmp === 0) { 7727 throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one'); 7728 } else if (!detectedIndent) { 7729 textIndent = nodeIndent + tmp - 1; 7730 detectedIndent = true; 7731 } else { 7732 throwError(state, 'repeat of an indentation width identifier'); 7733 } 7734 7735 } else { 7736 break; 7737 } 7738 } 7739 7740 if (is_WHITE_SPACE(ch)) { 7741 do { ch = state.input.charCodeAt(++state.position); } 7742 while (is_WHITE_SPACE(ch)); 7743 7744 if (ch === 0x23/* # */) { 7745 do { ch = state.input.charCodeAt(++state.position); } 7746 while (!is_EOL(ch) && (ch !== 0)); 7747 } 7748 } 7749 7750 while (ch !== 0) { 7751 readLineBreak(state); 7752 state.lineIndent = 0; 7753 7754 ch = state.input.charCodeAt(state.position); 7755 7756 while ((!detectedIndent || state.lineIndent < textIndent) && 7757 (ch === 0x20/* Space */)) { 7758 state.lineIndent++; 7759 ch = state.input.charCodeAt(++state.position); 7760 } 7761 7762 if (!detectedIndent && state.lineIndent > textIndent) { 7763 textIndent = state.lineIndent; 7764 } 7765 7766 if (is_EOL(ch)) { 7767 emptyLines++; 7768 continue; 7769 } 7770 7771 // End of the scalar. 7772 if (state.lineIndent < textIndent) { 7773 7774 // Perform the chomping. 7775 if (chomping === CHOMPING_KEEP) { 7776 state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); 7777 } else if (chomping === CHOMPING_CLIP) { 7778 if (didReadContent) { // i.e. only if the scalar is not empty. 7779 state.result += '\n'; 7780 } 7781 } 7782 7783 // Break this `while` cycle and go to the funciton's epilogue. 7784 break; 7785 } 7786 7787 // Folded style: use fancy rules to handle line breaks. 7788 if (folding) { 7789 7790 // Lines starting with white space characters (more-indented lines) are not folded. 7791 if (is_WHITE_SPACE(ch)) { 7792 atMoreIndented = true; 7793 // except for the first content line (cf. Example 8.1) 7794 state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); 7795 7796 // End of more-indented block. 7797 } else if (atMoreIndented) { 7798 atMoreIndented = false; 7799 state.result += common.repeat('\n', emptyLines + 1); 7800 7801 // Just one line break - perceive as the same line. 7802 } else if (emptyLines === 0) { 7803 if (didReadContent) { // i.e. only if we have already read some scalar content. 7804 state.result += ' '; 7805 } 7806 7807 // Several line breaks - perceive as different lines. 7808 } else { 7809 state.result += common.repeat('\n', emptyLines); 7810 } 7811 7812 // Literal style: just add exact number of line breaks between content lines. 7813 } else { 7814 // Keep all line breaks except the header line break. 7815 state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); 7816 } 7817 7818 didReadContent = true; 7819 detectedIndent = true; 7820 emptyLines = 0; 7821 captureStart = state.position; 7822 7823 while (!is_EOL(ch) && (ch !== 0)) { 7824 ch = state.input.charCodeAt(++state.position); 7825 } 7826 7827 captureSegment(state, captureStart, state.position, false); 7828 } 7829 7830 return true; 7831 } 7832 7833 function readBlockSequence(state, nodeIndent) { 7834 var _line, 7835 _tag = state.tag, 7836 _anchor = state.anchor, 7837 _result = [], 7838 following, 7839 detected = false, 7840 ch; 7841 7842 // there is a leading tab before this token, so it can't be a block sequence/mapping; 7843 // it can still be flow sequence/mapping or a scalar 7844 if (state.firstTabInLine !== -1) return false; 7845 7846 if (state.anchor !== null) { 7847 state.anchorMap[state.anchor] = _result; 7848 } 7849 7850 ch = state.input.charCodeAt(state.position); 7851 7852 while (ch !== 0) { 7853 if (state.firstTabInLine !== -1) { 7854 state.position = state.firstTabInLine; 7855 throwError(state, 'tab characters must not be used in indentation'); 7856 } 7857 7858 if (ch !== 0x2D/* - */) { 7859 break; 7860 } 7861 7862 following = state.input.charCodeAt(state.position + 1); 7863 7864 if (!is_WS_OR_EOL(following)) { 7865 break; 7866 } 7867 7868 detected = true; 7869 state.position++; 7870 7871 if (skipSeparationSpace(state, true, -1)) { 7872 if (state.lineIndent <= nodeIndent) { 7873 _result.push(null); 7874 ch = state.input.charCodeAt(state.position); 7875 continue; 7876 } 7877 } 7878 7879 _line = state.line; 7880 composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true); 7881 _result.push(state.result); 7882 skipSeparationSpace(state, true, -1); 7883 7884 ch = state.input.charCodeAt(state.position); 7885 7886 if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { 7887 throwError(state, 'bad indentation of a sequence entry'); 7888 } else if (state.lineIndent < nodeIndent) { 7889 break; 7890 } 7891 } 7892 7893 if (detected) { 7894 state.tag = _tag; 7895 state.anchor = _anchor; 7896 state.kind = 'sequence'; 7897 state.result = _result; 7898 return true; 7899 } 7900 return false; 7901 } 7902 7903 function readBlockMapping(state, nodeIndent, flowIndent) { 7904 var following, 7905 allowCompact, 7906 _line, 7907 _keyLine, 7908 _keyLineStart, 7909 _keyPos, 7910 _tag = state.tag, 7911 _anchor = state.anchor, 7912 _result = {}, 7913 overridableKeys = Object.create(null), 7914 keyTag = null, 7915 keyNode = null, 7916 valueNode = null, 7917 atExplicitKey = false, 7918 detected = false, 7919 ch; 7920 7921 // there is a leading tab before this token, so it can't be a block sequence/mapping; 7922 // it can still be flow sequence/mapping or a scalar 7923 if (state.firstTabInLine !== -1) return false; 7924 7925 if (state.anchor !== null) { 7926 state.anchorMap[state.anchor] = _result; 7927 } 7928 7929 ch = state.input.charCodeAt(state.position); 7930 7931 while (ch !== 0) { 7932 if (!atExplicitKey && state.firstTabInLine !== -1) { 7933 state.position = state.firstTabInLine; 7934 throwError(state, 'tab characters must not be used in indentation'); 7935 } 7936 7937 following = state.input.charCodeAt(state.position + 1); 7938 _line = state.line; // Save the current line. 7939 7940 // 7941 // Explicit notation case. There are two separate blocks: 7942 // first for the key (denoted by "?") and second for the value (denoted by ":") 7943 // 7944 if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) { 7945 7946 if (ch === 0x3F/* ? */) { 7947 if (atExplicitKey) { 7948 storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); 7949 keyTag = keyNode = valueNode = null; 7950 } 7951 7952 detected = true; 7953 atExplicitKey = true; 7954 allowCompact = true; 7955 7956 } else if (atExplicitKey) { 7957 // i.e. 0x3A/* : */ === character after the explicit key. 7958 atExplicitKey = false; 7959 allowCompact = true; 7960 7961 } else { 7962 throwError(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line'); 7963 } 7964 7965 state.position += 1; 7966 ch = following; 7967 7968 // 7969 // Implicit notation case. Flow-style node as the key first, then ":", and the value. 7970 // 7971 } else { 7972 _keyLine = state.line; 7973 _keyLineStart = state.lineStart; 7974 _keyPos = state.position; 7975 7976 if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) { 7977 // Neither implicit nor explicit notation. 7978 // Reading is done. Go to the epilogue. 7979 break; 7980 } 7981 7982 if (state.line === _line) { 7983 ch = state.input.charCodeAt(state.position); 7984 7985 while (is_WHITE_SPACE(ch)) { 7986 ch = state.input.charCodeAt(++state.position); 7987 } 7988 7989 if (ch === 0x3A/* : */) { 7990 ch = state.input.charCodeAt(++state.position); 7991 7992 if (!is_WS_OR_EOL(ch)) { 7993 throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping'); 7994 } 7995 7996 if (atExplicitKey) { 7997 storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); 7998 keyTag = keyNode = valueNode = null; 7999 } 8000 8001 detected = true; 8002 atExplicitKey = false; 8003 allowCompact = false; 8004 keyTag = state.tag; 8005 keyNode = state.result; 8006 8007 } else if (detected) { 8008 throwError(state, 'can not read an implicit mapping pair; a colon is missed'); 8009 8010 } else { 8011 state.tag = _tag; 8012 state.anchor = _anchor; 8013 return true; // Keep the result of `composeNode`. 8014 } 8015 8016 } else if (detected) { 8017 throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key'); 8018 8019 } else { 8020 state.tag = _tag; 8021 state.anchor = _anchor; 8022 return true; // Keep the result of `composeNode`. 8023 } 8024 } 8025 8026 // 8027 // Common reading code for both explicit and implicit notations. 8028 // 8029 if (state.line === _line || state.lineIndent > nodeIndent) { 8030 if (atExplicitKey) { 8031 _keyLine = state.line; 8032 _keyLineStart = state.lineStart; 8033 _keyPos = state.position; 8034 } 8035 8036 if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) { 8037 if (atExplicitKey) { 8038 keyNode = state.result; 8039 } else { 8040 valueNode = state.result; 8041 } 8042 } 8043 8044 if (!atExplicitKey) { 8045 storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos); 8046 keyTag = keyNode = valueNode = null; 8047 } 8048 8049 skipSeparationSpace(state, true, -1); 8050 ch = state.input.charCodeAt(state.position); 8051 } 8052 8053 if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { 8054 throwError(state, 'bad indentation of a mapping entry'); 8055 } else if (state.lineIndent < nodeIndent) { 8056 break; 8057 } 8058 } 8059 8060 // 8061 // Epilogue. 8062 // 8063 8064 // Special case: last mapping's node contains only the key in explicit notation. 8065 if (atExplicitKey) { 8066 storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); 8067 } 8068 8069 // Expose the resulting mapping. 8070 if (detected) { 8071 state.tag = _tag; 8072 state.anchor = _anchor; 8073 state.kind = 'mapping'; 8074 state.result = _result; 8075 } 8076 8077 return detected; 8078 } 8079 8080 function readTagProperty(state) { 8081 var _position, 8082 isVerbatim = false, 8083 isNamed = false, 8084 tagHandle, 8085 tagName, 8086 ch; 8087 8088 ch = state.input.charCodeAt(state.position); 8089 8090 if (ch !== 0x21/* ! */) return false; 8091 8092 if (state.tag !== null) { 8093 throwError(state, 'duplication of a tag property'); 8094 } 8095 8096 ch = state.input.charCodeAt(++state.position); 8097 8098 if (ch === 0x3C/* < */) { 8099 isVerbatim = true; 8100 ch = state.input.charCodeAt(++state.position); 8101 8102 } else if (ch === 0x21/* ! */) { 8103 isNamed = true; 8104 tagHandle = '!!'; 8105 ch = state.input.charCodeAt(++state.position); 8106 8107 } else { 8108 tagHandle = '!'; 8109 } 8110 8111 _position = state.position; 8112 8113 if (isVerbatim) { 8114 do { ch = state.input.charCodeAt(++state.position); } 8115 while (ch !== 0 && ch !== 0x3E/* > */); 8116 8117 if (state.position < state.length) { 8118 tagName = state.input.slice(_position, state.position); 8119 ch = state.input.charCodeAt(++state.position); 8120 } else { 8121 throwError(state, 'unexpected end of the stream within a verbatim tag'); 8122 } 8123 } else { 8124 while (ch !== 0 && !is_WS_OR_EOL(ch)) { 8125 8126 if (ch === 0x21/* ! */) { 8127 if (!isNamed) { 8128 tagHandle = state.input.slice(_position - 1, state.position + 1); 8129 8130 if (!PATTERN_TAG_HANDLE.test(tagHandle)) { 8131 throwError(state, 'named tag handle cannot contain such characters'); 8132 } 8133 8134 isNamed = true; 8135 _position = state.position + 1; 8136 } else { 8137 throwError(state, 'tag suffix cannot contain exclamation marks'); 8138 } 8139 } 8140 8141 ch = state.input.charCodeAt(++state.position); 8142 } 8143 8144 tagName = state.input.slice(_position, state.position); 8145 8146 if (PATTERN_FLOW_INDICATORS.test(tagName)) { 8147 throwError(state, 'tag suffix cannot contain flow indicator characters'); 8148 } 8149 } 8150 8151 if (tagName && !PATTERN_TAG_URI.test(tagName)) { 8152 throwError(state, 'tag name cannot contain such characters: ' + tagName); 8153 } 8154 8155 try { 8156 tagName = decodeURIComponent(tagName); 8157 } catch (err) { 8158 throwError(state, 'tag name is malformed: ' + tagName); 8159 } 8160 8161 if (isVerbatim) { 8162 state.tag = tagName; 8163 8164 } else if (_hasOwnProperty$1.call(state.tagMap, tagHandle)) { 8165 state.tag = state.tagMap[tagHandle] + tagName; 8166 8167 } else if (tagHandle === '!') { 8168 state.tag = '!' + tagName; 8169 8170 } else if (tagHandle === '!!') { 8171 state.tag = 'tag:yaml.org,2002:' + tagName; 8172 8173 } else { 8174 throwError(state, 'undeclared tag handle "' + tagHandle + '"'); 8175 } 8176 8177 return true; 8178 } 8179 8180 function readAnchorProperty(state) { 8181 var _position, 8182 ch; 8183 8184 ch = state.input.charCodeAt(state.position); 8185 8186 if (ch !== 0x26/* & */) return false; 8187 8188 if (state.anchor !== null) { 8189 throwError(state, 'duplication of an anchor property'); 8190 } 8191 8192 ch = state.input.charCodeAt(++state.position); 8193 _position = state.position; 8194 8195 while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { 8196 ch = state.input.charCodeAt(++state.position); 8197 } 8198 8199 if (state.position === _position) { 8200 throwError(state, 'name of an anchor node must contain at least one character'); 8201 } 8202 8203 state.anchor = state.input.slice(_position, state.position); 8204 return true; 8205 } 8206 8207 function readAlias(state) { 8208 var _position, alias, 8209 ch; 8210 8211 ch = state.input.charCodeAt(state.position); 8212 8213 if (ch !== 0x2A/* * */) return false; 8214 8215 ch = state.input.charCodeAt(++state.position); 8216 _position = state.position; 8217 8218 while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { 8219 ch = state.input.charCodeAt(++state.position); 8220 } 8221 8222 if (state.position === _position) { 8223 throwError(state, 'name of an alias node must contain at least one character'); 8224 } 8225 8226 alias = state.input.slice(_position, state.position); 8227 8228 if (!_hasOwnProperty$1.call(state.anchorMap, alias)) { 8229 throwError(state, 'unidentified alias "' + alias + '"'); 8230 } 8231 8232 state.result = state.anchorMap[alias]; 8233 skipSeparationSpace(state, true, -1); 8234 return true; 8235 } 8236 8237 function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) { 8238 var allowBlockStyles, 8239 allowBlockScalars, 8240 allowBlockCollections, 8241 indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this<parent 8242 atNewLine = false, 8243 hasContent = false, 8244 typeIndex, 8245 typeQuantity, 8246 typeList, 8247 type, 8248 flowIndent, 8249 blockIndent; 8250 8251 if (state.listener !== null) { 8252 state.listener('open', state); 8253 } 8254 8255 state.tag = null; 8256 state.anchor = null; 8257 state.kind = null; 8258 state.result = null; 8259 8260 allowBlockStyles = allowBlockScalars = allowBlockCollections = 8261 CONTEXT_BLOCK_OUT === nodeContext || 8262 CONTEXT_BLOCK_IN === nodeContext; 8263 8264 if (allowToSeek) { 8265 if (skipSeparationSpace(state, true, -1)) { 8266 atNewLine = true; 8267 8268 if (state.lineIndent > parentIndent) { 8269 indentStatus = 1; 8270 } else if (state.lineIndent === parentIndent) { 8271 indentStatus = 0; 8272 } else if (state.lineIndent < parentIndent) { 8273 indentStatus = -1; 8274 } 8275 } 8276 } 8277 8278 if (indentStatus === 1) { 8279 while (readTagProperty(state) || readAnchorProperty(state)) { 8280 if (skipSeparationSpace(state, true, -1)) { 8281 atNewLine = true; 8282 allowBlockCollections = allowBlockStyles; 8283 8284 if (state.lineIndent > parentIndent) { 8285 indentStatus = 1; 8286 } else if (state.lineIndent === parentIndent) { 8287 indentStatus = 0; 8288 } else if (state.lineIndent < parentIndent) { 8289 indentStatus = -1; 8290 } 8291 } else { 8292 allowBlockCollections = false; 8293 } 8294 } 8295 } 8296 8297 if (allowBlockCollections) { 8298 allowBlockCollections = atNewLine || allowCompact; 8299 } 8300 8301 if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) { 8302 if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) { 8303 flowIndent = parentIndent; 8304 } else { 8305 flowIndent = parentIndent + 1; 8306 } 8307 8308 blockIndent = state.position - state.lineStart; 8309 8310 if (indentStatus === 1) { 8311 if (allowBlockCollections && 8312 (readBlockSequence(state, blockIndent) || 8313 readBlockMapping(state, blockIndent, flowIndent)) || 8314 readFlowCollection(state, flowIndent)) { 8315 hasContent = true; 8316 } else { 8317 if ((allowBlockScalars && readBlockScalar(state, flowIndent)) || 8318 readSingleQuotedScalar(state, flowIndent) || 8319 readDoubleQuotedScalar(state, flowIndent)) { 8320 hasContent = true; 8321 8322 } else if (readAlias(state)) { 8323 hasContent = true; 8324 8325 if (state.tag !== null || state.anchor !== null) { 8326 throwError(state, 'alias node should not have any properties'); 8327 } 8328 8329 } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) { 8330 hasContent = true; 8331 8332 if (state.tag === null) { 8333 state.tag = '?'; 8334 } 8335 } 8336 8337 if (state.anchor !== null) { 8338 state.anchorMap[state.anchor] = state.result; 8339 } 8340 } 8341 } else if (indentStatus === 0) { 8342 // Special case: block sequences are allowed to have same indentation level as the parent. 8343 // http://www.yaml.org/spec/1.2/spec.html#id2799784 8344 hasContent = allowBlockCollections && readBlockSequence(state, blockIndent); 8345 } 8346 } 8347 8348 if (state.tag === null) { 8349 if (state.anchor !== null) { 8350 state.anchorMap[state.anchor] = state.result; 8351 } 8352 8353 } else if (state.tag === '?') { 8354 // Implicit resolving is not allowed for non-scalar types, and '?' 8355 // non-specific tag is only automatically assigned to plain scalars. 8356 // 8357 // We only need to check kind conformity in case user explicitly assigns '?' 8358 // tag, for example like this: "!<?> [0]" 8359 // 8360 if (state.result !== null && state.kind !== 'scalar') { 8361 throwError(state, 'unacceptable node kind for !<?> tag; it should be "scalar", not "' + state.kind + '"'); 8362 } 8363 8364 for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) { 8365 type = state.implicitTypes[typeIndex]; 8366 8367 if (type.resolve(state.result)) { // `state.result` updated in resolver if matched 8368 state.result = type.construct(state.result); 8369 state.tag = type.tag; 8370 if (state.anchor !== null) { 8371 state.anchorMap[state.anchor] = state.result; 8372 } 8373 break; 8374 } 8375 } 8376 } else if (state.tag !== '!') { 8377 if (_hasOwnProperty$1.call(state.typeMap[state.kind || 'fallback'], state.tag)) { 8378 type = state.typeMap[state.kind || 'fallback'][state.tag]; 8379 } else { 8380 // looking for multi type 8381 type = null; 8382 typeList = state.typeMap.multi[state.kind || 'fallback']; 8383 8384 for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) { 8385 if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) { 8386 type = typeList[typeIndex]; 8387 break; 8388 } 8389 } 8390 } 8391 8392 if (!type) { 8393 throwError(state, 'unknown tag !<' + state.tag + '>'); 8394 } 8395 8396 if (state.result !== null && type.kind !== state.kind) { 8397 throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"'); 8398 } 8399 8400 if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched 8401 throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag'); 8402 } else { 8403 state.result = type.construct(state.result, state.tag); 8404 if (state.anchor !== null) { 8405 state.anchorMap[state.anchor] = state.result; 8406 } 8407 } 8408 } 8409 8410 if (state.listener !== null) { 8411 state.listener('close', state); 8412 } 8413 return state.tag !== null || state.anchor !== null || hasContent; 8414 } 8415 8416 function readDocument(state) { 8417 var documentStart = state.position, 8418 _position, 8419 directiveName, 8420 directiveArgs, 8421 hasDirectives = false, 8422 ch; 8423 8424 state.version = null; 8425 state.checkLineBreaks = state.legacy; 8426 state.tagMap = Object.create(null); 8427 state.anchorMap = Object.create(null); 8428 8429 while ((ch = state.input.charCodeAt(state.position)) !== 0) { 8430 skipSeparationSpace(state, true, -1); 8431 8432 ch = state.input.charCodeAt(state.position); 8433 8434 if (state.lineIndent > 0 || ch !== 0x25/* % */) { 8435 break; 8436 } 8437 8438 hasDirectives = true; 8439 ch = state.input.charCodeAt(++state.position); 8440 _position = state.position; 8441 8442 while (ch !== 0 && !is_WS_OR_EOL(ch)) { 8443 ch = state.input.charCodeAt(++state.position); 8444 } 8445 8446 directiveName = state.input.slice(_position, state.position); 8447 directiveArgs = []; 8448 8449 if (directiveName.length < 1) { 8450 throwError(state, 'directive name must not be less than one character in length'); 8451 } 8452 8453 while (ch !== 0) { 8454 while (is_WHITE_SPACE(ch)) { 8455 ch = state.input.charCodeAt(++state.position); 8456 } 8457 8458 if (ch === 0x23/* # */) { 8459 do { ch = state.input.charCodeAt(++state.position); } 8460 while (ch !== 0 && !is_EOL(ch)); 8461 break; 8462 } 8463 8464 if (is_EOL(ch)) break; 8465 8466 _position = state.position; 8467 8468 while (ch !== 0 && !is_WS_OR_EOL(ch)) { 8469 ch = state.input.charCodeAt(++state.position); 8470 } 8471 8472 directiveArgs.push(state.input.slice(_position, state.position)); 8473 } 8474 8475 if (ch !== 0) readLineBreak(state); 8476 8477 if (_hasOwnProperty$1.call(directiveHandlers, directiveName)) { 8478 directiveHandlers[directiveName](state, directiveName, directiveArgs); 8479 } else { 8480 throwWarning(state, 'unknown document directive "' + directiveName + '"'); 8481 } 8482 } 8483 8484 skipSeparationSpace(state, true, -1); 8485 8486 if (state.lineIndent === 0 && 8487 state.input.charCodeAt(state.position) === 0x2D/* - */ && 8488 state.input.charCodeAt(state.position + 1) === 0x2D/* - */ && 8489 state.input.charCodeAt(state.position + 2) === 0x2D/* - */) { 8490 state.position += 3; 8491 skipSeparationSpace(state, true, -1); 8492 8493 } else if (hasDirectives) { 8494 throwError(state, 'directives end mark is expected'); 8495 } 8496 8497 composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true); 8498 skipSeparationSpace(state, true, -1); 8499 8500 if (state.checkLineBreaks && 8501 PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) { 8502 throwWarning(state, 'non-ASCII line breaks are interpreted as content'); 8503 } 8504 8505 state.documents.push(state.result); 8506 8507 if (state.position === state.lineStart && testDocumentSeparator(state)) { 8508 8509 if (state.input.charCodeAt(state.position) === 0x2E/* . */) { 8510 state.position += 3; 8511 skipSeparationSpace(state, true, -1); 8512 } 8513 return; 8514 } 8515 8516 if (state.position < (state.length - 1)) { 8517 throwError(state, 'end of the stream or a document separator is expected'); 8518 } else { 8519 return; 8520 } 8521 } 8522 8523 8524 function loadDocuments(input, options) { 8525 input = String(input); 8526 options = options || {}; 8527 8528 if (input.length !== 0) { 8529 8530 // Add tailing `\n` if not exists 8531 if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ && 8532 input.charCodeAt(input.length - 1) !== 0x0D/* CR */) { 8533 input += '\n'; 8534 } 8535 8536 // Strip BOM 8537 if (input.charCodeAt(0) === 0xFEFF) { 8538 input = input.slice(1); 8539 } 8540 } 8541 8542 var state = new State$1(input, options); 8543 8544 var nullpos = input.indexOf('\0'); 8545 8546 if (nullpos !== -1) { 8547 state.position = nullpos; 8548 throwError(state, 'null byte is not allowed in input'); 8549 } 8550 8551 // Use 0 as string terminator. That significantly simplifies bounds check. 8552 state.input += '\0'; 8553 8554 while (state.input.charCodeAt(state.position) === 0x20/* Space */) { 8555 state.lineIndent += 1; 8556 state.position += 1; 8557 } 8558 8559 while (state.position < (state.length - 1)) { 8560 readDocument(state); 8561 } 8562 8563 return state.documents; 8564 } 8565 8566 8567 function loadAll$1(input, iterator, options) { 8568 if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') { 8569 options = iterator; 8570 iterator = null; 8571 } 8572 8573 var documents = loadDocuments(input, options); 8574 8575 if (typeof iterator !== 'function') { 8576 return documents; 8577 } 8578 8579 for (var index = 0, length = documents.length; index < length; index += 1) { 8580 iterator(documents[index]); 8581 } 8582 } 8583 8584 8585 function load$1(input, options) { 8586 var documents = loadDocuments(input, options); 8587 8588 if (documents.length === 0) { 8589 /*eslint-disable no-undefined*/ 8590 return undefined; 8591 } else if (documents.length === 1) { 8592 return documents[0]; 8593 } 8594 throw new exception('expected a single document in the stream, but found more'); 8595 } 8596 8597 8598 var loadAll_1 = loadAll$1; 8599 var load_1 = load$1; 8600 8601 var loader = { 8602 loadAll: loadAll_1, 8603 load: load_1 8604 }; 8605 8606 /*eslint-disable no-use-before-define*/ 8607 8608 8609 8610 8611 8612 var _toString = Object.prototype.toString; 8613 var _hasOwnProperty = Object.prototype.hasOwnProperty; 8614 8615 var CHAR_BOM = 0xFEFF; 8616 var CHAR_TAB = 0x09; /* Tab */ 8617 var CHAR_LINE_FEED = 0x0A; /* LF */ 8618 var CHAR_CARRIAGE_RETURN = 0x0D; /* CR */ 8619 var CHAR_SPACE = 0x20; /* Space */ 8620 var CHAR_EXCLAMATION = 0x21; /* ! */ 8621 var CHAR_DOUBLE_QUOTE = 0x22; /* " */ 8622 var CHAR_SHARP = 0x23; /* # */ 8623 var CHAR_PERCENT = 0x25; /* % */ 8624 var CHAR_AMPERSAND = 0x26; /* & */ 8625 var CHAR_SINGLE_QUOTE = 0x27; /* ' */ 8626 var CHAR_ASTERISK = 0x2A; /* * */ 8627 var CHAR_COMMA = 0x2C; /* , */ 8628 var CHAR_MINUS = 0x2D; /* - */ 8629 var CHAR_COLON = 0x3A; /* : */ 8630 var CHAR_EQUALS = 0x3D; /* = */ 8631 var CHAR_GREATER_THAN = 0x3E; /* > */ 8632 var CHAR_QUESTION = 0x3F; /* ? */ 8633 var CHAR_COMMERCIAL_AT = 0x40; /* @ */ 8634 var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ 8635 var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ 8636 var CHAR_GRAVE_ACCENT = 0x60; /* ` */ 8637 var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ 8638 var CHAR_VERTICAL_LINE = 0x7C; /* | */ 8639 var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ 8640 8641 var ESCAPE_SEQUENCES = {}; 8642 8643 ESCAPE_SEQUENCES[0x00] = '\\0'; 8644 ESCAPE_SEQUENCES[0x07] = '\\a'; 8645 ESCAPE_SEQUENCES[0x08] = '\\b'; 8646 ESCAPE_SEQUENCES[0x09] = '\\t'; 8647 ESCAPE_SEQUENCES[0x0A] = '\\n'; 8648 ESCAPE_SEQUENCES[0x0B] = '\\v'; 8649 ESCAPE_SEQUENCES[0x0C] = '\\f'; 8650 ESCAPE_SEQUENCES[0x0D] = '\\r'; 8651 ESCAPE_SEQUENCES[0x1B] = '\\e'; 8652 ESCAPE_SEQUENCES[0x22] = '\\"'; 8653 ESCAPE_SEQUENCES[0x5C] = '\\\\'; 8654 ESCAPE_SEQUENCES[0x85] = '\\N'; 8655 ESCAPE_SEQUENCES[0xA0] = '\\_'; 8656 ESCAPE_SEQUENCES[0x2028] = '\\L'; 8657 ESCAPE_SEQUENCES[0x2029] = '\\P'; 8658 8659 var DEPRECATED_BOOLEANS_SYNTAX = [ 8660 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON', 8661 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF' 8662 ]; 8663 8664 var DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/; 8665 8666 function compileStyleMap(schema, map) { 8667 var result, keys, index, length, tag, style, type; 8668 8669 if (map === null) return {}; 8670 8671 result = {}; 8672 keys = Object.keys(map); 8673 8674 for (index = 0, length = keys.length; index < length; index += 1) { 8675 tag = keys[index]; 8676 style = String(map[tag]); 8677 8678 if (tag.slice(0, 2) === '!!') { 8679 tag = 'tag:yaml.org,2002:' + tag.slice(2); 8680 } 8681 type = schema.compiledTypeMap['fallback'][tag]; 8682 8683 if (type && _hasOwnProperty.call(type.styleAliases, style)) { 8684 style = type.styleAliases[style]; 8685 } 8686 8687 result[tag] = style; 8688 } 8689 8690 return result; 8691 } 8692 8693 function encodeHex(character) { 8694 var string, handle, length; 8695 8696 string = character.toString(16).toUpperCase(); 8697 8698 if (character <= 0xFF) { 8699 handle = 'x'; 8700 length = 2; 8701 } else if (character <= 0xFFFF) { 8702 handle = 'u'; 8703 length = 4; 8704 } else if (character <= 0xFFFFFFFF) { 8705 handle = 'U'; 8706 length = 8; 8707 } else { 8708 throw new exception('code point within a string may not be greater than 0xFFFFFFFF'); 8709 } 8710 8711 return '\\' + handle + common.repeat('0', length - string.length) + string; 8712 } 8713 8714 8715 var QUOTING_TYPE_SINGLE = 1, 8716 QUOTING_TYPE_DOUBLE = 2; 8717 8718 function State(options) { 8719 this.schema = options['schema'] || _default; 8720 this.indent = Math.max(1, (options['indent'] || 2)); 8721 this.noArrayIndent = options['noArrayIndent'] || false; 8722 this.skipInvalid = options['skipInvalid'] || false; 8723 this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']); 8724 this.styleMap = compileStyleMap(this.schema, options['styles'] || null); 8725 this.sortKeys = options['sortKeys'] || false; 8726 this.lineWidth = options['lineWidth'] || 80; 8727 this.noRefs = options['noRefs'] || false; 8728 this.noCompatMode = options['noCompatMode'] || false; 8729 this.condenseFlow = options['condenseFlow'] || false; 8730 this.quotingType = options['quotingType'] === '"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE; 8731 this.forceQuotes = options['forceQuotes'] || false; 8732 this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null; 8733 8734 this.implicitTypes = this.schema.compiledImplicit; 8735 this.explicitTypes = this.schema.compiledExplicit; 8736 8737 this.tag = null; 8738 this.result = ''; 8739 8740 this.duplicates = []; 8741 this.usedDuplicates = null; 8742 } 8743 8744 // Indents every line in a string. Empty lines (\n only) are not indented. 8745 function indentString(string, spaces) { 8746 var ind = common.repeat(' ', spaces), 8747 position = 0, 8748 next = -1, 8749 result = '', 8750 line, 8751 length = string.length; 8752 8753 while (position < length) { 8754 next = string.indexOf('\n', position); 8755 if (next === -1) { 8756 line = string.slice(position); 8757 position = length; 8758 } else { 8759 line = string.slice(position, next + 1); 8760 position = next + 1; 8761 } 8762 8763 if (line.length && line !== '\n') result += ind; 8764 8765 result += line; 8766 } 8767 8768 return result; 8769 } 8770 8771 function generateNextLine(state, level) { 8772 return '\n' + common.repeat(' ', state.indent * level); 8773 } 8774 8775 function testImplicitResolving(state, str) { 8776 var index, length, type; 8777 8778 for (index = 0, length = state.implicitTypes.length; index < length; index += 1) { 8779 type = state.implicitTypes[index]; 8780 8781 if (type.resolve(str)) { 8782 return true; 8783 } 8784 } 8785 8786 return false; 8787 } 8788 8789 // [33] s-white ::= s-space | s-tab 8790 function isWhitespace(c) { 8791 return c === CHAR_SPACE || c === CHAR_TAB; 8792 } 8793 8794 // Returns true if the character can be printed without escaping. 8795 // From YAML 1.2: "any allowed characters known to be non-printable 8796 // should also be escaped. [However,] This isn’t mandatory" 8797 // Derived from nb-char - \t - #x85 - #xA0 - #x2028 - #x2029. 8798 function isPrintable(c) { 8799 return (0x00020 <= c && c <= 0x00007E) 8800 || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029) 8801 || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM) 8802 || (0x10000 <= c && c <= 0x10FFFF); 8803 } 8804 8805 // [34] ns-char ::= nb-char - s-white 8806 // [27] nb-char ::= c-printable - b-char - c-byte-order-mark 8807 // [26] b-char ::= b-line-feed | b-carriage-return 8808 // Including s-white (for some reason, examples doesn't match specs in this aspect) 8809 // ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark 8810 function isNsCharOrWhitespace(c) { 8811 return isPrintable(c) 8812 && c !== CHAR_BOM 8813 // - b-char 8814 && c !== CHAR_CARRIAGE_RETURN 8815 && c !== CHAR_LINE_FEED; 8816 } 8817 8818 // [127] ns-plain-safe(c) ::= c = flow-out ⇒ ns-plain-safe-out 8819 // c = flow-in ⇒ ns-plain-safe-in 8820 // c = block-key ⇒ ns-plain-safe-out 8821 // c = flow-key ⇒ ns-plain-safe-in 8822 // [128] ns-plain-safe-out ::= ns-char 8823 // [129] ns-plain-safe-in ::= ns-char - c-flow-indicator 8824 // [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - “:” - “#” ) 8825 // | ( /* An ns-char preceding */ “#” ) 8826 // | ( “:” /* Followed by an ns-plain-safe(c) */ ) 8827 function isPlainSafe(c, prev, inblock) { 8828 var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c); 8829 var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c); 8830 return ( 8831 // ns-plain-safe 8832 inblock ? // c = flow-in 8833 cIsNsCharOrWhitespace 8834 : cIsNsCharOrWhitespace 8835 // - c-flow-indicator 8836 && c !== CHAR_COMMA 8837 && c !== CHAR_LEFT_SQUARE_BRACKET 8838 && c !== CHAR_RIGHT_SQUARE_BRACKET 8839 && c !== CHAR_LEFT_CURLY_BRACKET 8840 && c !== CHAR_RIGHT_CURLY_BRACKET 8841 ) 8842 // ns-plain-char 8843 && c !== CHAR_SHARP // false on '#' 8844 && !(prev === CHAR_COLON && !cIsNsChar) // false on ': ' 8845 || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#' 8846 || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]' 8847 } 8848 8849 // Simplified test for values allowed as the first character in plain style. 8850 function isPlainSafeFirst(c) { 8851 // Uses a subset of ns-char - c-indicator 8852 // where ns-char = nb-char - s-white. 8853 // No support of ( ( “?” | “:” | “-” ) /* Followed by an ns-plain-safe(c)) */ ) part 8854 return isPrintable(c) && c !== CHAR_BOM 8855 && !isWhitespace(c) // - s-white 8856 // - (c-indicator ::= 8857 // “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}” 8858 && c !== CHAR_MINUS 8859 && c !== CHAR_QUESTION 8860 && c !== CHAR_COLON 8861 && c !== CHAR_COMMA 8862 && c !== CHAR_LEFT_SQUARE_BRACKET 8863 && c !== CHAR_RIGHT_SQUARE_BRACKET 8864 && c !== CHAR_LEFT_CURLY_BRACKET 8865 && c !== CHAR_RIGHT_CURLY_BRACKET 8866 // | “#” | “&” | “*” | “!” | “|” | “=” | “>” | “'” | “"” 8867 && c !== CHAR_SHARP 8868 && c !== CHAR_AMPERSAND 8869 && c !== CHAR_ASTERISK 8870 && c !== CHAR_EXCLAMATION 8871 && c !== CHAR_VERTICAL_LINE 8872 && c !== CHAR_EQUALS 8873 && c !== CHAR_GREATER_THAN 8874 && c !== CHAR_SINGLE_QUOTE 8875 && c !== CHAR_DOUBLE_QUOTE 8876 // | “%” | “@” | “`”) 8877 && c !== CHAR_PERCENT 8878 && c !== CHAR_COMMERCIAL_AT 8879 && c !== CHAR_GRAVE_ACCENT; 8880 } 8881 8882 // Simplified test for values allowed as the last character in plain style. 8883 function isPlainSafeLast(c) { 8884 // just not whitespace or colon, it will be checked to be plain character later 8885 return !isWhitespace(c) && c !== CHAR_COLON; 8886 } 8887 8888 // Same as 'string'.codePointAt(pos), but works in older browsers. 8889 function codePointAt(string, pos) { 8890 var first = string.charCodeAt(pos), second; 8891 if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) { 8892 second = string.charCodeAt(pos + 1); 8893 if (second >= 0xDC00 && second <= 0xDFFF) { 8894 // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae 8895 return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000; 8896 } 8897 } 8898 return first; 8899 } 8900 8901 // Determines whether block indentation indicator is required. 8902 function needIndentIndicator(string) { 8903 var leadingSpaceRe = /^\n* /; 8904 return leadingSpaceRe.test(string); 8905 } 8906 8907 var STYLE_PLAIN = 1, 8908 STYLE_SINGLE = 2, 8909 STYLE_LITERAL = 3, 8910 STYLE_FOLDED = 4, 8911 STYLE_DOUBLE = 5; 8912 8913 // Determines which scalar styles are possible and returns the preferred style. 8914 // lineWidth = -1 => no limit. 8915 // Pre-conditions: str.length > 0. 8916 // Post-conditions: 8917 // STYLE_PLAIN or STYLE_SINGLE => no \n are in the string. 8918 // STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1). 8919 // STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1). 8920 function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, 8921 testAmbiguousType, quotingType, forceQuotes, inblock) { 8922 8923 var i; 8924 var char = 0; 8925 var prevChar = null; 8926 var hasLineBreak = false; 8927 var hasFoldableLine = false; // only checked if shouldTrackWidth 8928 var shouldTrackWidth = lineWidth !== -1; 8929 var previousLineBreak = -1; // count the first line correctly 8930 var plain = isPlainSafeFirst(codePointAt(string, 0)) 8931 && isPlainSafeLast(codePointAt(string, string.length - 1)); 8932 8933 if (singleLineOnly || forceQuotes) { 8934 // Case: no block styles. 8935 // Check for disallowed characters to rule out plain and single. 8936 for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { 8937 char = codePointAt(string, i); 8938 if (!isPrintable(char)) { 8939 return STYLE_DOUBLE; 8940 } 8941 plain = plain && isPlainSafe(char, prevChar, inblock); 8942 prevChar = char; 8943 } 8944 } else { 8945 // Case: block styles permitted. 8946 for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { 8947 char = codePointAt(string, i); 8948 if (char === CHAR_LINE_FEED) { 8949 hasLineBreak = true; 8950 // Check if any line can be folded. 8951 if (shouldTrackWidth) { 8952 hasFoldableLine = hasFoldableLine || 8953 // Foldable line = too long, and not more-indented. 8954 (i - previousLineBreak - 1 > lineWidth && 8955 string[previousLineBreak + 1] !== ' '); 8956 previousLineBreak = i; 8957 } 8958 } else if (!isPrintable(char)) { 8959 return STYLE_DOUBLE; 8960 } 8961 plain = plain && isPlainSafe(char, prevChar, inblock); 8962 prevChar = char; 8963 } 8964 // in case the end is missing a \n 8965 hasFoldableLine = hasFoldableLine || (shouldTrackWidth && 8966 (i - previousLineBreak - 1 > lineWidth && 8967 string[previousLineBreak + 1] !== ' ')); 8968 } 8969 // Although every style can represent \n without escaping, prefer block styles 8970 // for multiline, since they're more readable and they don't add empty lines. 8971 // Also prefer folding a super-long line. 8972 if (!hasLineBreak && !hasFoldableLine) { 8973 // Strings interpretable as another type have to be quoted; 8974 // e.g. the string 'true' vs. the boolean true. 8975 if (plain && !forceQuotes && !testAmbiguousType(string)) { 8976 return STYLE_PLAIN; 8977 } 8978 return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE; 8979 } 8980 // Edge case: block indentation indicator can only have one digit. 8981 if (indentPerLevel > 9 && needIndentIndicator(string)) { 8982 return STYLE_DOUBLE; 8983 } 8984 // At this point we know block styles are valid. 8985 // Prefer literal style unless we want to fold. 8986 if (!forceQuotes) { 8987 return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL; 8988 } 8989 return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE; 8990 } 8991 8992 // Note: line breaking/folding is implemented for only the folded style. 8993 // NB. We drop the last trailing newline (if any) of a returned block scalar 8994 // since the dumper adds its own newline. This always works: 8995 // • No ending newline => unaffected; already using strip "-" chomping. 8996 // • Ending newline => removed then restored. 8997 // Importantly, this keeps the "+" chomp indicator from gaining an extra line. 8998 function writeScalar(state, string, level, iskey, inblock) { 8999 state.dump = (function () { 9000 if (string.length === 0) { 9001 return state.quotingType === QUOTING_TYPE_DOUBLE ? '""' : "''"; 9002 } 9003 if (!state.noCompatMode) { 9004 if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) { 9005 return state.quotingType === QUOTING_TYPE_DOUBLE ? ('"' + string + '"') : ("'" + string + "'"); 9006 } 9007 } 9008 9009 var indent = state.indent * Math.max(1, level); // no 0-indent scalars 9010 // As indentation gets deeper, let the width decrease monotonically 9011 // to the lower bound min(state.lineWidth, 40). 9012 // Note that this implies 9013 // state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound. 9014 // state.lineWidth > 40 + state.indent: width decreases until the lower bound. 9015 // This behaves better than a constant minimum width which disallows narrower options, 9016 // or an indent threshold which causes the width to suddenly increase. 9017 var lineWidth = state.lineWidth === -1 9018 ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent); 9019 9020 // Without knowing if keys are implicit/explicit, assume implicit for safety. 9021 var singleLineOnly = iskey 9022 // No block styles in flow mode. 9023 || (state.flowLevel > -1 && level >= state.flowLevel); 9024 function testAmbiguity(string) { 9025 return testImplicitResolving(state, string); 9026 } 9027 9028 switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth, 9029 testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) { 9030 9031 case STYLE_PLAIN: 9032 return string; 9033 case STYLE_SINGLE: 9034 return "'" + string.replace(/'/g, "''") + "'"; 9035 case STYLE_LITERAL: 9036 return '|' + blockHeader(string, state.indent) 9037 + dropEndingNewline(indentString(string, indent)); 9038 case STYLE_FOLDED: 9039 return '>' + blockHeader(string, state.indent) 9040 + dropEndingNewline(indentString(foldString(string, lineWidth), indent)); 9041 case STYLE_DOUBLE: 9042 return '"' + escapeString(string) + '"'; 9043 default: 9044 throw new exception('impossible error: invalid scalar style'); 9045 } 9046 }()); 9047 } 9048 9049 // Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9. 9050 function blockHeader(string, indentPerLevel) { 9051 var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : ''; 9052 9053 // note the special case: the string '\n' counts as a "trailing" empty line. 9054 var clip = string[string.length - 1] === '\n'; 9055 var keep = clip && (string[string.length - 2] === '\n' || string === '\n'); 9056 var chomp = keep ? '+' : (clip ? '' : '-'); 9057 9058 return indentIndicator + chomp + '\n'; 9059 } 9060 9061 // (See the note for writeScalar.) 9062 function dropEndingNewline(string) { 9063 return string[string.length - 1] === '\n' ? string.slice(0, -1) : string; 9064 } 9065 9066 // Note: a long line without a suitable break point will exceed the width limit. 9067 // Pre-conditions: every char in str isPrintable, str.length > 0, width > 0. 9068 function foldString(string, width) { 9069 // In folded style, $k$ consecutive newlines output as $k+1$ newlines— 9070 // unless they're before or after a more-indented line, or at the very 9071 // beginning or end, in which case $k$ maps to $k$. 9072 // Therefore, parse each chunk as newline(s) followed by a content line. 9073 var lineRe = /(\n+)([^\n]*)/g; 9074 9075 // first line (possibly an empty line) 9076 var result = (function () { 9077 var nextLF = string.indexOf('\n'); 9078 nextLF = nextLF !== -1 ? nextLF : string.length; 9079 lineRe.lastIndex = nextLF; 9080 return foldLine(string.slice(0, nextLF), width); 9081 }()); 9082 // If we haven't reached the first content line yet, don't add an extra \n. 9083 var prevMoreIndented = string[0] === '\n' || string[0] === ' '; 9084 var moreIndented; 9085 9086 // rest of the lines 9087 var match; 9088 while ((match = lineRe.exec(string))) { 9089 var prefix = match[1], line = match[2]; 9090 moreIndented = (line[0] === ' '); 9091 result += prefix 9092 + (!prevMoreIndented && !moreIndented && line !== '' 9093 ? '\n' : '') 9094 + foldLine(line, width); 9095 prevMoreIndented = moreIndented; 9096 } 9097 9098 return result; 9099 } 9100 9101 // Greedy line breaking. 9102 // Picks the longest line under the limit each time, 9103 // otherwise settles for the shortest line over the limit. 9104 // NB. More-indented lines *cannot* be folded, as that would add an extra \n. 9105 function foldLine(line, width) { 9106 if (line === '' || line[0] === ' ') return line; 9107 9108 // Since a more-indented line adds a \n, breaks can't be followed by a space. 9109 var breakRe = / [^ ]/g; // note: the match index will always be <= length-2. 9110 var match; 9111 // start is an inclusive index. end, curr, and next are exclusive. 9112 var start = 0, end, curr = 0, next = 0; 9113 var result = ''; 9114 9115 // Invariants: 0 <= start <= length-1. 9116 // 0 <= curr <= next <= max(0, length-2). curr - start <= width. 9117 // Inside the loop: 9118 // A match implies length >= 2, so curr and next are <= length-2. 9119 while ((match = breakRe.exec(line))) { 9120 next = match.index; 9121 // maintain invariant: curr - start <= width 9122 if (next - start > width) { 9123 end = (curr > start) ? curr : next; // derive end <= length-2 9124 result += '\n' + line.slice(start, end); 9125 // skip the space that was output as \n 9126 start = end + 1; // derive start <= length-1 9127 } 9128 curr = next; 9129 } 9130 9131 // By the invariants, start <= length-1, so there is something left over. 9132 // It is either the whole string or a part starting from non-whitespace. 9133 result += '\n'; 9134 // Insert a break if the remainder is too long and there is a break available. 9135 if (line.length - start > width && curr > start) { 9136 result += line.slice(start, curr) + '\n' + line.slice(curr + 1); 9137 } else { 9138 result += line.slice(start); 9139 } 9140 9141 return result.slice(1); // drop extra \n joiner 9142 } 9143 9144 // Escapes a double-quoted string. 9145 function escapeString(string) { 9146 var result = ''; 9147 var char = 0; 9148 var escapeSeq; 9149 9150 for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { 9151 char = codePointAt(string, i); 9152 escapeSeq = ESCAPE_SEQUENCES[char]; 9153 9154 if (!escapeSeq && isPrintable(char)) { 9155 result += string[i]; 9156 if (char >= 0x10000) result += string[i + 1]; 9157 } else { 9158 result += escapeSeq || encodeHex(char); 9159 } 9160 } 9161 9162 return result; 9163 } 9164 9165 function writeFlowSequence(state, level, object) { 9166 var _result = '', 9167 _tag = state.tag, 9168 index, 9169 length, 9170 value; 9171 9172 for (index = 0, length = object.length; index < length; index += 1) { 9173 value = object[index]; 9174 9175 if (state.replacer) { 9176 value = state.replacer.call(object, String(index), value); 9177 } 9178 9179 // Write only valid elements, put null instead of invalid elements. 9180 if (writeNode(state, level, value, false, false) || 9181 (typeof value === 'undefined' && 9182 writeNode(state, level, null, false, false))) { 9183 9184 if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : ''); 9185 _result += state.dump; 9186 } 9187 } 9188 9189 state.tag = _tag; 9190 state.dump = '[' + _result + ']'; 9191 } 9192 9193 function writeBlockSequence(state, level, object, compact) { 9194 var _result = '', 9195 _tag = state.tag, 9196 index, 9197 length, 9198 value; 9199 9200 for (index = 0, length = object.length; index < length; index += 1) { 9201 value = object[index]; 9202 9203 if (state.replacer) { 9204 value = state.replacer.call(object, String(index), value); 9205 } 9206 9207 // Write only valid elements, put null instead of invalid elements. 9208 if (writeNode(state, level + 1, value, true, true, false, true) || 9209 (typeof value === 'undefined' && 9210 writeNode(state, level + 1, null, true, true, false, true))) { 9211 9212 if (!compact || _result !== '') { 9213 _result += generateNextLine(state, level); 9214 } 9215 9216 if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { 9217 _result += '-'; 9218 } else { 9219 _result += '- '; 9220 } 9221 9222 _result += state.dump; 9223 } 9224 } 9225 9226 state.tag = _tag; 9227 state.dump = _result || '[]'; // Empty sequence if no valid values. 9228 } 9229 9230 function writeFlowMapping(state, level, object) { 9231 var _result = '', 9232 _tag = state.tag, 9233 objectKeyList = Object.keys(object), 9234 index, 9235 length, 9236 objectKey, 9237 objectValue, 9238 pairBuffer; 9239 9240 for (index = 0, length = objectKeyList.length; index < length; index += 1) { 9241 9242 pairBuffer = ''; 9243 if (_result !== '') pairBuffer += ', '; 9244 9245 if (state.condenseFlow) pairBuffer += '"'; 9246 9247 objectKey = objectKeyList[index]; 9248 objectValue = object[objectKey]; 9249 9250 if (state.replacer) { 9251 objectValue = state.replacer.call(object, objectKey, objectValue); 9252 } 9253 9254 if (!writeNode(state, level, objectKey, false, false)) { 9255 continue; // Skip this pair because of invalid key; 9256 } 9257 9258 if (state.dump.length > 1024) pairBuffer += '? '; 9259 9260 pairBuffer += state.dump + (state.condenseFlow ? '"' : '') + ':' + (state.condenseFlow ? '' : ' '); 9261 9262 if (!writeNode(state, level, objectValue, false, false)) { 9263 continue; // Skip this pair because of invalid value. 9264 } 9265 9266 pairBuffer += state.dump; 9267 9268 // Both key and value are valid. 9269 _result += pairBuffer; 9270 } 9271 9272 state.tag = _tag; 9273 state.dump = '{' + _result + '}'; 9274 } 9275 9276 function writeBlockMapping(state, level, object, compact) { 9277 var _result = '', 9278 _tag = state.tag, 9279 objectKeyList = Object.keys(object), 9280 index, 9281 length, 9282 objectKey, 9283 objectValue, 9284 explicitPair, 9285 pairBuffer; 9286 9287 // Allow sorting keys so that the output file is deterministic 9288 if (state.sortKeys === true) { 9289 // Default sorting 9290 objectKeyList.sort(); 9291 } else if (typeof state.sortKeys === 'function') { 9292 // Custom sort function 9293 objectKeyList.sort(state.sortKeys); 9294 } else if (state.sortKeys) { 9295 // Something is wrong 9296 throw new exception('sortKeys must be a boolean or a function'); 9297 } 9298 9299 for (index = 0, length = objectKeyList.length; index < length; index += 1) { 9300 pairBuffer = ''; 9301 9302 if (!compact || _result !== '') { 9303 pairBuffer += generateNextLine(state, level); 9304 } 9305 9306 objectKey = objectKeyList[index]; 9307 objectValue = object[objectKey]; 9308 9309 if (state.replacer) { 9310 objectValue = state.replacer.call(object, objectKey, objectValue); 9311 } 9312 9313 if (!writeNode(state, level + 1, objectKey, true, true, true)) { 9314 continue; // Skip this pair because of invalid key. 9315 } 9316 9317 explicitPair = (state.tag !== null && state.tag !== '?') || 9318 (state.dump && state.dump.length > 1024); 9319 9320 if (explicitPair) { 9321 if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { 9322 pairBuffer += '?'; 9323 } else { 9324 pairBuffer += '? '; 9325 } 9326 } 9327 9328 pairBuffer += state.dump; 9329 9330 if (explicitPair) { 9331 pairBuffer += generateNextLine(state, level); 9332 } 9333 9334 if (!writeNode(state, level + 1, objectValue, true, explicitPair)) { 9335 continue; // Skip this pair because of invalid value. 9336 } 9337 9338 if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { 9339 pairBuffer += ':'; 9340 } else { 9341 pairBuffer += ': '; 9342 } 9343 9344 pairBuffer += state.dump; 9345 9346 // Both key and value are valid. 9347 _result += pairBuffer; 9348 } 9349 9350 state.tag = _tag; 9351 state.dump = _result || '{}'; // Empty mapping if no valid pairs. 9352 } 9353 9354 function detectType(state, object, explicit) { 9355 var _result, typeList, index, length, type, style; 9356 9357 typeList = explicit ? state.explicitTypes : state.implicitTypes; 9358 9359 for (index = 0, length = typeList.length; index < length; index += 1) { 9360 type = typeList[index]; 9361 9362 if ((type.instanceOf || type.predicate) && 9363 (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) && 9364 (!type.predicate || type.predicate(object))) { 9365 9366 if (explicit) { 9367 if (type.multi && type.representName) { 9368 state.tag = type.representName(object); 9369 } else { 9370 state.tag = type.tag; 9371 } 9372 } else { 9373 state.tag = '?'; 9374 } 9375 9376 if (type.represent) { 9377 style = state.styleMap[type.tag] || type.defaultStyle; 9378 9379 if (_toString.call(type.represent) === '[object Function]') { 9380 _result = type.represent(object, style); 9381 } else if (_hasOwnProperty.call(type.represent, style)) { 9382 _result = type.represent[style](object, style); 9383 } else { 9384 throw new exception('!<' + type.tag + '> tag resolver accepts not "' + style + '" style'); 9385 } 9386 9387 state.dump = _result; 9388 } 9389 9390 return true; 9391 } 9392 } 9393 9394 return false; 9395 } 9396 9397 // Serializes `object` and writes it to global `result`. 9398 // Returns true on success, or false on invalid object. 9399 // 9400 function writeNode(state, level, object, block, compact, iskey, isblockseq) { 9401 state.tag = null; 9402 state.dump = object; 9403 9404 if (!detectType(state, object, false)) { 9405 detectType(state, object, true); 9406 } 9407 9408 var type = _toString.call(state.dump); 9409 var inblock = block; 9410 var tagStr; 9411 9412 if (block) { 9413 block = (state.flowLevel < 0 || state.flowLevel > level); 9414 } 9415 9416 var objectOrArray = type === '[object Object]' || type === '[object Array]', 9417 duplicateIndex, 9418 duplicate; 9419 9420 if (objectOrArray) { 9421 duplicateIndex = state.duplicates.indexOf(object); 9422 duplicate = duplicateIndex !== -1; 9423 } 9424 9425 if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) { 9426 compact = false; 9427 } 9428 9429 if (duplicate && state.usedDuplicates[duplicateIndex]) { 9430 state.dump = '*ref_' + duplicateIndex; 9431 } else { 9432 if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) { 9433 state.usedDuplicates[duplicateIndex] = true; 9434 } 9435 if (type === '[object Object]') { 9436 if (block && (Object.keys(state.dump).length !== 0)) { 9437 writeBlockMapping(state, level, state.dump, compact); 9438 if (duplicate) { 9439 state.dump = '&ref_' + duplicateIndex + state.dump; 9440 } 9441 } else { 9442 writeFlowMapping(state, level, state.dump); 9443 if (duplicate) { 9444 state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; 9445 } 9446 } 9447 } else if (type === '[object Array]') { 9448 if (block && (state.dump.length !== 0)) { 9449 if (state.noArrayIndent && !isblockseq && level > 0) { 9450 writeBlockSequence(state, level - 1, state.dump, compact); 9451 } else { 9452 writeBlockSequence(state, level, state.dump, compact); 9453 } 9454 if (duplicate) { 9455 state.dump = '&ref_' + duplicateIndex + state.dump; 9456 } 9457 } else { 9458 writeFlowSequence(state, level, state.dump); 9459 if (duplicate) { 9460 state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; 9461 } 9462 } 9463 } else if (type === '[object String]') { 9464 if (state.tag !== '?') { 9465 writeScalar(state, state.dump, level, iskey, inblock); 9466 } 9467 } else if (type === '[object Undefined]') { 9468 return false; 9469 } else { 9470 if (state.skipInvalid) return false; 9471 throw new exception('unacceptable kind of an object to dump ' + type); 9472 } 9473 9474 if (state.tag !== null && state.tag !== '?') { 9475 // Need to encode all characters except those allowed by the spec: 9476 // 9477 // [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */ 9478 // [36] ns-hex-digit ::= ns-dec-digit 9479 // | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */ 9480 // [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */ 9481 // [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | “-” 9482 // [39] ns-uri-char ::= “%” ns-hex-digit ns-hex-digit | ns-word-char | “#” 9483 // | “;” | “/” | “?” | “:” | “@” | “&” | “=” | “+” | “$” | “,” 9484 // | “_” | “.” | “!” | “~” | “*” | “'” | “(” | “)” | “[” | “]” 9485 // 9486 // Also need to encode '!' because it has special meaning (end of tag prefix). 9487 // 9488 tagStr = encodeURI( 9489 state.tag[0] === '!' ? state.tag.slice(1) : state.tag 9490 ).replace(/!/g, '%21'); 9491 9492 if (state.tag[0] === '!') { 9493 tagStr = '!' + tagStr; 9494 } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') { 9495 tagStr = '!!' + tagStr.slice(18); 9496 } else { 9497 tagStr = '!<' + tagStr + '>'; 9498 } 9499 9500 state.dump = tagStr + ' ' + state.dump; 9501 } 9502 } 9503 9504 return true; 9505 } 9506 9507 function getDuplicateReferences(object, state) { 9508 var objects = [], 9509 duplicatesIndexes = [], 9510 index, 9511 length; 9512 9513 inspectNode(object, objects, duplicatesIndexes); 9514 9515 for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) { 9516 state.duplicates.push(objects[duplicatesIndexes[index]]); 9517 } 9518 state.usedDuplicates = new Array(length); 9519 } 9520 9521 function inspectNode(object, objects, duplicatesIndexes) { 9522 var objectKeyList, 9523 index, 9524 length; 9525 9526 if (object !== null && typeof object === 'object') { 9527 index = objects.indexOf(object); 9528 if (index !== -1) { 9529 if (duplicatesIndexes.indexOf(index) === -1) { 9530 duplicatesIndexes.push(index); 9531 } 9532 } else { 9533 objects.push(object); 9534 9535 if (Array.isArray(object)) { 9536 for (index = 0, length = object.length; index < length; index += 1) { 9537 inspectNode(object[index], objects, duplicatesIndexes); 9538 } 9539 } else { 9540 objectKeyList = Object.keys(object); 9541 9542 for (index = 0, length = objectKeyList.length; index < length; index += 1) { 9543 inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes); 9544 } 9545 } 9546 } 9547 } 9548 } 9549 9550 function dump$1(input, options) { 9551 options = options || {}; 9552 9553 var state = new State(options); 9554 9555 if (!state.noRefs) getDuplicateReferences(input, state); 9556 9557 var value = input; 9558 9559 if (state.replacer) { 9560 value = state.replacer.call({ '': value }, '', value); 9561 } 9562 9563 if (writeNode(state, 0, value, true, true)) return state.dump + '\n'; 9564 9565 return ''; 9566 } 9567 9568 var dump_1 = dump$1; 9569 9570 var dumper = { 9571 dump: dump_1 9572 }; 9573 9574 function renamed(from, to) { 9575 return function () { 9576 throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' + 9577 'Use yaml.' + to + ' instead, which is now safe by default.'); 9578 }; 9579 } 9580 9581 9582 var Type = type; 9583 var Schema = schema; 9584 var FAILSAFE_SCHEMA = failsafe; 9585 var JSON_SCHEMA = json; 9586 var CORE_SCHEMA = core; 9587 var DEFAULT_SCHEMA = _default; 9588 var load = loader.load; 9589 var loadAll = loader.loadAll; 9590 var dump = dumper.dump; 9591 var YAMLException = exception; 9592 9593 // Re-export all types in case user wants to create custom schema 9594 var types = { 9595 binary: binary, 9596 float: float, 9597 map: map, 9598 null: _null, 9599 pairs: pairs, 9600 set: set, 9601 timestamp: timestamp, 9602 bool: bool, 9603 int: int, 9604 merge: merge, 9605 omap: omap, 9606 seq: seq, 9607 str: str 9608 }; 9609 9610 // Removed functions from JS-YAML 3.0.x 9611 var safeLoad = renamed('safeLoad', 'load'); 9612 var safeLoadAll = renamed('safeLoadAll', 'loadAll'); 9613 var safeDump = renamed('safeDump', 'dump'); 9614 9615 var jsYaml = { 9616 Type: Type, 9617 Schema: Schema, 9618 FAILSAFE_SCHEMA: FAILSAFE_SCHEMA, 9619 JSON_SCHEMA: JSON_SCHEMA, 9620 CORE_SCHEMA: CORE_SCHEMA, 9621 DEFAULT_SCHEMA: DEFAULT_SCHEMA, 9622 load: load, 9623 loadAll: loadAll, 9624 dump: dump, 9625 YAMLException: YAMLException, 9626 types: types, 9627 safeLoad: safeLoad, 9628 safeLoadAll: safeLoadAll, 9629 safeDump: safeDump 9630 }; 9631 9632 class CSSSettingsPlugin extends obsidian.Plugin { 9633 constructor() { 9634 super(...arguments); 9635 this.settingsList = []; 9636 this.errorList = []; 9637 this.commandList = []; 9638 this.debounceTimer = 0; 9639 } 9640 onload() { 9641 return __awaiter(this, void 0, void 0, function* () { 9642 this.settingsManager = new CSSSettingsManager(this); 9643 yield this.settingsManager.load(); 9644 this.settingsTab = new CSSSettingsTab(this.app, this); 9645 this.addSettingTab(this.settingsTab); 9646 this.registerView(viewType, (leaf) => new SettingsView(this, leaf)); 9647 this.addCommand({ 9648 id: 'show-style-settings-leaf', 9649 name: 'Show style settings view', 9650 callback: () => { 9651 this.activateView(); 9652 }, 9653 }); 9654 this.registerEvent(this.app.workspace.on('css-change', (data) => { 9655 if ((data === null || data === void 0 ? void 0 : data.source) !== 'style-settings') { 9656 this.parseCSS(); 9657 } 9658 })); 9659 this.registerEvent(this.app.workspace.on('parse-style-settings', () => { 9660 this.parseCSS(); 9661 })); 9662 this.lightEl = document.body.createDiv('theme-light style-settings-ref'); 9663 this.darkEl = document.body.createDiv('theme-dark style-settings-ref'); 9664 document.body.classList.add('css-settings-manager'); 9665 this.parseCSS(); 9666 this.app.workspace.onLayoutReady(() => { 9667 if (this.settingsList) { 9668 this.app.workspace.getLeavesOfType(viewType).forEach((leaf) => { 9669 leaf.view.setSettings(this.settingsList, this.errorList); 9670 }); 9671 } 9672 }); 9673 }); 9674 } 9675 getCSSVar(id) { 9676 const light = getComputedStyle(this.lightEl).getPropertyValue(`--${id}`); 9677 const dark = getComputedStyle(this.darkEl).getPropertyValue(`--${id}`); 9678 const current = getComputedStyle(document.body).getPropertyValue(`--${id}`); 9679 return { light, dark, current }; 9680 } 9681 parseCSS() { 9682 clearTimeout(this.debounceTimer); 9683 this.debounceTimer = activeWindow.setTimeout(() => { 9684 this.settingsList = []; 9685 this.errorList = []; 9686 // remove registered theme commands (sadly undocumented API) 9687 for (const command of this.commandList) { 9688 // @ts-ignore 9689 this.app.commands.removeCommand(command.id); 9690 } 9691 this.commandList = []; 9692 this.settingsManager.removeClasses(); 9693 const styleSheets = document.styleSheets; 9694 for (let i = 0, len = styleSheets.length; i < len; i++) { 9695 const sheet = styleSheets.item(i); 9696 this.parseCSSStyleSheet(sheet); 9697 } 9698 // compatability with Settings Search Plugin 9699 this.registerSettingsToSettingsSearch(); 9700 this.settingsTab.setSettings(this.settingsList, this.errorList); 9701 this.app.workspace.getLeavesOfType(viewType).forEach((leaf) => { 9702 leaf.view.setSettings(this.settingsList, this.errorList); 9703 }); 9704 this.settingsManager.setConfig(this.settingsList); 9705 this.settingsManager.initClasses(); 9706 this.registerSettingCommands(); 9707 }, 100); 9708 } 9709 /** 9710 * Registers the current settings to the settings search plugin. 9711 * It also unregisters the old settings. 9712 * 9713 * @private 9714 */ 9715 registerSettingsToSettingsSearch() { 9716 var _a; 9717 const onSettingsSearchLoaded = () => { 9718 if (window.SettingsSearch) { 9719 const settingsSearch = window.SettingsSearch; 9720 settingsSearch.removeTabResources('obsidian-style-settings'); 9721 for (const parsedCSSSetting of this.settingsList) { 9722 settingsSearch.addResources(...parsedCSSSetting.settings.map((x) => { 9723 var _a, _b; 9724 const settingsSearchResource = { 9725 tab: 'obsidian-style-settings', 9726 name: 'Style Settings', 9727 text: (_a = getTitle(x)) !== null && _a !== void 0 ? _a : '', 9728 desc: (_b = getDescription(x)) !== null && _b !== void 0 ? _b : '', 9729 }; 9730 return settingsSearchResource; 9731 })); 9732 } 9733 } 9734 }; 9735 // @ts-ignore TODO: expand obsidian types, so that the ts-ignore is not needed 9736 if ((_a = this.app.plugins.plugins['settings-search']) === null || _a === void 0 ? void 0 : _a.loaded) { 9737 onSettingsSearchLoaded(); 9738 } 9739 else { 9740 // @ts-ignore 9741 this.app.workspace.on('settings-search-loaded', () => { 9742 onSettingsSearchLoaded(); 9743 }); 9744 } 9745 } 9746 /** 9747 * Remove any settings from settings search if settings search is loaded. 9748 * 9749 * @private 9750 */ 9751 unregisterSettingsFromSettingsSearch() { 9752 var _a; 9753 // @ts-ignore TODO: expand obsidian types, so that the ts-ignore is not needed 9754 if ((_a = this.app.plugins.plugins['settings-search']) === null || _a === void 0 ? void 0 : _a.loaded) { 9755 // @ts-ignore 9756 window.SettingsSearch.removeTabResources('obsidian-style-settings'); 9757 } 9758 } 9759 /** 9760 * Parses the settings from a css style sheet. 9761 * Adds the parsed settings to `settingsList` and any errors to `errorList`. 9762 * 9763 * @param sheet the stylesheet to parse 9764 * @private 9765 */ 9766 parseCSSStyleSheet(sheet) { 9767 const text = sheet.ownerNode.textContent.trim(); 9768 let match = settingRegExp.exec(text); 9769 if (match && match.length) { 9770 do { 9771 const nameMatch = text.match(nameRegExp); 9772 const name = nameMatch ? nameMatch[1] : undefined; 9773 try { 9774 const str = match[1].trim(); 9775 const settings = this.parseCSSSettings(str, name); 9776 if (settings && 9777 typeof settings === 'object' && 9778 settings.name && 9779 settings.id && 9780 settings.settings && 9781 settings.settings.length) { 9782 this.settingsList.push(settings); 9783 } 9784 } 9785 catch (e) { 9786 this.errorList.push({ name, error: `${e}` }); 9787 } 9788 } while ((match = settingRegExp.exec(text)) !== null); 9789 } 9790 } 9791 /** 9792 * Parse css settings from a string. 9793 * 9794 * @param str the stringified settings to parse 9795 * @param name the name of the file 9796 * @private 9797 */ 9798 parseCSSSettings(str, name) { 9799 const indent = detectIndent(str); 9800 const settings = jsYaml.load(str.replace(/\t/g, indent.type === 'space' ? indent.indent : ' '), { 9801 filename: name, 9802 }); 9803 if (!settings.settings) 9804 return undefined; 9805 settings.settings = settings.settings.filter((setting) => setting); 9806 return settings; 9807 } 9808 registerSettingCommands() { 9809 for (const section of this.settingsList) { 9810 for (const setting of section.settings) { 9811 if (setting.type === SettingType.CLASS_TOGGLE && 9812 setting.addCommand) { 9813 this.addClassToggleCommand(section, setting); 9814 } 9815 } 9816 } 9817 } 9818 addClassToggleCommand(section, setting) { 9819 this.commandList.push(this.addCommand({ 9820 id: `style-settings-class-toggle-${section.id}-${setting.id}`, 9821 name: `Toggle ${setting.title}`, 9822 callback: () => { 9823 const value = !this.settingsManager.getSetting(section.id, setting.id); 9824 this.settingsManager.setSetting(section.id, setting.id, value); 9825 this.settingsTab.rerender(); 9826 for (const leaf of this.app.workspace.getLeavesOfType(viewType)) { 9827 leaf.view.rerender(); 9828 } 9829 }, 9830 })); 9831 } 9832 onunload() { 9833 this.lightEl.remove(); 9834 this.darkEl.remove(); 9835 this.lightEl = null; 9836 this.darkEl = null; 9837 document.body.classList.remove('css-settings-manager'); 9838 this.settingsManager.cleanup(); 9839 this.deactivateView(); 9840 this.unregisterSettingsFromSettingsSearch(); 9841 } 9842 deactivateView() { 9843 this.app.workspace.detachLeavesOfType(viewType); 9844 } 9845 activateView() { 9846 return __awaiter(this, void 0, void 0, function* () { 9847 this.deactivateView(); 9848 const leaf = this.app.workspace.getLeaf('tab'); 9849 yield leaf.setViewState({ 9850 type: viewType, 9851 active: true, 9852 }); 9853 leaf.view.setSettings(this.settingsList, this.errorList); 9854 }); 9855 } 9856 } 9857 9858 module.exports = CSSSettingsPlugin;