1(function (factory) { 2 typeof define === 'function' && define.amd ? define(factory) : 3 factory(); 4}((function () { 'use strict'; 5 6 // Copyright 2018 The Distill Template Authors 7 // 8 // Licensed under the Apache License, Version 2.0 (the "License"); 9 // you may not use this file except in compliance with the License. 10 // You may obtain a copy of the License at 11 // 12 // http://www.apache.org/licenses/LICENSE-2.0 13 // 14 // Unless required by applicable law or agreed to in writing, software 15 // distributed under the License is distributed on an "AS IS" BASIS, 16 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 // See the License for the specific language governing permissions and 18 // limitations under the License. 19 20 const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; 21 const months = ['Jan.', 'Feb.', 'March', 'April', 'May', 'June', 'July', 'Aug.', 'Sept.', 'Oct.', 'Nov.', 'Dec.']; 22 const zeroPad = n => n < 10 ? '0' + n : n; 23 24 const RFC = function(date) { 25 const day = days[date.getDay()].substring(0, 3); 26 const paddedDate = zeroPad(date.getDate());
27 const month = months[date.getMonth()].substring(0,3); 28 const year = date.getFullYear().toString(); 29 const hours = date.getUTCHours().toString(); 30 const minutes = date.getUTCMinutes().toString(); 31 const seconds = date.getUTCSeconds().toString(); 32 return `${day}, ${paddedDate} ${month} ${year} ${hours}:${minutes}:${seconds} Z`; 33 }; 34 35 const objectFromMap = function(map) { 36 const object = Array.from(map).reduce((object, [key, value]) => ( 37 Object.assign(object, { [key]: value }) // Be careful! Maps can have non-String keys; object literals can't. 38 ), {}); 39 return object; 40 }; 41 42 const mapFromObject = function(object) { 43 const map = new Map(); 44 for (var property in object) { 45 if (object.hasOwnProperty(property)) { 46 map.set(property, object[property]); 47 } 48 } 49 return map; 50 }; 51 52 class Author { 53 54 // constructor(name='', personalURL='', affiliation='', affiliationURL='') { 55 // this.name = name; // 'Chris Olah' 56 // this.personalURL = personalURL; // 'https://colah.github.io' 57 // this.affiliation = affiliation; // 'Google Brain' 58 // this.affiliationURL = affiliationURL; // 'https://g.co/brain' 59 // } 60 61 constructor(object) { 62 this.name = object.author; // 'Chris Olah' 63 this.personalURL = object.authorURL; // 'https://colah.github.io' 64 this.affiliation = object.affiliation; // 'Google Brain' 65 this.affiliationURL = object.affiliationURL; // 'https://g.co/brain' 66 this.affiliations = object.affiliations || []; // new-style affiliations 67 } 68 69 // 'Chris' 70 get firstName() { 71 const names = this.name.split(' '); 72 return names.slice(0, names.length - 1).join(' '); 73 } 74 75 // 'Olah' 76 get lastName() { 77 const names = this.name.split(' '); 78 return names[names.length -1]; 79 } 80 } 81 82 function mergeFromYMLFrontmatter(target, source) { 83 target.title = source.title; 84 if (source.published) { 85 if (source.published instanceof Date) { 86 target.publishedDate = source.published; 87 } else if (source.published.constructor === String) { 88 target.publishedDate = new Date(source.published); 89 } 90 } 91 if (source.publishedDate) { 92 if (source.publishedDate instanceof Date) { 93 target.publishedDate = source.publishedDate; 94 } else if (source.publishedDate.constructor === String) { 95 target.publishedDate = new Date(source.publishedDate); 96 } else { 97 console.error('Don\'t know what to do with published date: ' + source.publishedDate); 98 } 99 } 100 target.description = source.description; 101 target.authors = source.authors.map( (authorObject) => new Author(authorObject)); 102 target.katex = source.katex; 103 target.password = source.password; 104 if (source.doi) { 105 target.doi = source.doi; 106 } 107 } 108 109 class FrontMatter { 110 constructor() { 111 this.title = 'unnamed article'; // 'Attention and Augmented Recurrent Neural Networks' 112 this.description = ''; // 'A visual overview of neural attention...' 113 this.authors = []; // Array of Author(s) 114 115 this.bibliography = new Map(); 116 this.bibliographyParsed = false; 117 // { 118 // 'gregor2015draw': { 119 // 'title': 'DRAW: A recurrent neural network for image generation', 120 // 'author': 'Gregor, Karol and Danihelka, Ivo and Graves, Alex and Rezende, Danilo Jimenez and Wierstra, Daan', 121 // 'journal': 'arXiv preprint arXiv:1502.04623', 122 // 'year': '2015', 123 // 'url': 'https://arxiv.org/pdf/1502.04623.pdf', 124 // 'type': 'article' 125 // }, 126 // } 127 128 // Citation keys should be listed in the order that they are appear in the document. 129 // Each key refers to a key in the bibliography dictionary. 130 this.citations = []; // [ 'gregor2015draw', 'mercier2011humans' ] 131 this.citationsCollected = false; 132 133 // 134 // Assigned from posts.csv 135 // 136 137 // publishedDate: 2016-09-08T07:00:00.000Z, 138 // tags: [ 'rnn' ], 139 // distillPath: '2016/augmented-rnns', 140 // githubPath: 'distillpub/post--augmented-rnns', 141 // doiSuffix: 1, 142 143 // 144 // Assigned from journal 145 // 146 this.journal = {}; 147 // journal: { 148 // 'title': 'Distill', 149 // 'full_title': 'Distill', 150 // 'abbrev_title': 'Distill', 151 // 'url': 'http://distill.pub', 152 // 'doi': '10.23915/distill', 153 // 'publisherName': 'Distill Working Group', 154 // 'publisherEmail': '[email protected]', 155 // 'issn': '2476-0757', 156 // 'editors': [...], 157 // 'committee': [...] 158 // } 159 // volume: 1, 160 // issue: 9, 161 162 this.katex = {}; 163 164 // 165 // Assigned from publishing process 166 // 167 168 // githubCompareUpdatesUrl: 'https://github.com/distillpub/post--augmented-rnns/compare/1596e094d8943d2dc0ea445d92071129c6419c59...3bd9209e0c24d020f87cf6152dcecc6017cbc193', 169 // updatedDate: 2017-03-21T07:13:16.000Z, 170 // doi: '10.23915/distill.00001', 171 this.doi = undefined; 172 this.publishedDate = undefined; 173 } 174 175 // Example: 176 // title: Demo Title Attention and Augmented Recurrent Neural Networks 177 // published: Jan 10, 2017 178 // authors: 179 // - Chris Olah: 180 // - Shan Carter: http://shancarter.com 181 // affiliations: 182 // - Google Brain: 183 // - Google Brain: http://g.co/brain 184 185 // 186 // Computed Properties 187 // 188 189 // 'http://distill.pub/2016/augmented-rnns',
190 set url(value) { 191 this._url = value; 192 } 193 get url() { 194 if (this._url) { 195 return this._url; 196 } else if (this.distillPath && this.journal.url) { 197 return this.journal.url + '/' + this.distillPath; 198 } else if (this.journal.url) { 199 return this.journal.url; 200 } 201 } 202 203 // 'https://github.com/distillpub/post--augmented-rnns', 204 get githubUrl() { 205 if (this.githubPath) { 206 return 'https://github.com/' + this.githubPath; 207 } else { 208 return undefined; 209 } 210 } 211 212 // TODO resolve differences in naming of URL/Url/url. 213 // 'http://distill.pub/2016/augmented-rnns/thumbnail.jpg', 214 set previewURL(value) { 215 this._previewURL = value; 216 } 217 get previewURL() { 218 return this._previewURL ? this._previewURL : this.url + '/thumbnail.jpg'; 219 } 220 221 // 'Thu, 08 Sep 2016 00:00:00 -0700', 222 get publishedDateRFC() { 223 return RFC(this.publishedDate); 224 } 225 226 // 'Thu, 08 Sep 2016 00:00:00 -0700', 227 get updatedDateRFC() { 228 return RFC(this.updatedDate); 229 } 230 231 // 2016, 232 get publishedYear() { 233 return this.publishedDate.getFullYear(); 234 } 235 236 // 'Sept', 237 get publishedMonth() { 238 return months[this.publishedDate.getMonth()]; 239 } 240 241 // 8, 242 get publishedDay() { 243 return this.publishedDate.getDate(); 244 } 245 246 // '09', 247 get publishedMonthPadded() { 248 return zeroPad(this.publishedDate.getMonth() + 1); 249 } 250 251 // '08', 252 get publishedDayPadded() { 253 return zeroPad(this.publishedDate.getDate()); 254 } 255 256 get publishedISODateOnly() { 257 return this.publishedDate.toISOString().split('T')[0]; 258 } 259 260 get volume() { 261 const volume = this.publishedYear - 2015; 262 if (volume < 1) { 263 throw new Error('Invalid publish date detected during computing volume'); 264 } 265 return volume; 266 } 267 268 get issue() { 269 return this.publishedDate.getMonth() + 1; 270 } 271 272 // 'Olah & Carter', 273 get concatenatedAuthors() { 274 if (this.authors.length > 2) { 275 return this.authors[0].lastName + ', et al.'; 276 } else if (this.authors.length === 2) { 277 return this.authors[0].lastName + ' & ' + this.authors[1].lastName; 278 } else if (this.authors.length === 1) { 279 return this.authors[0].lastName; 280 } 281 } 282 283 // 'Olah, Chris and Carter, Shan', 284 get bibtexAuthors() { 285 return this.authors.map(author => { 286 return author.lastName + ', ' + author.firstName; 287 }).join(' and '); 288 } 289 290 // 'olah2016attention' 291 get slug() { 292 let slug = ''; 293 if (this.authors.length) { 294 slug += this.authors[0].lastName.toLowerCase(); 295 slug += this.publishedYear; 296 slug += this.title.split(' ')[0].toLowerCase(); 297 } 298 return slug || 'Untitled'; 299 } 300 301 get bibliographyEntries() { 302 return new Map(this.citations.map( citationKey => { 303 const entry = this.bibliography.get(citationKey); 304 return [citationKey, entry]; 305 })); 306 } 307 308 set bibliography(bibliography) { 309 if (bibliography instanceof Map) { 310 this._bibliography = bibliography; 311 } else if (typeof bibliography === 'object') { 312 this._bibliography = mapFromObject(bibliography); 313 } 314 } 315 316 get bibliography() { 317 return this._bibliography; 318 } 319 320 static fromObject(source) { 321 const frontMatter = new FrontMatter(); 322 Object.assign(frontMatter, source); 323 return frontMatter; 324 } 325 326 assignToObject(target) { 327 Object.assign(target, this); 328 target.bibliography = objectFromMap(this.bibliographyEntries); 329 target.url = this.url; 330 target.doi = this.doi; 331 target.githubUrl = this.githubUrl; 332 target.previewURL = this.previewURL; 333 if (this.publishedDate) { 334 target.volume = this.volume; 335 target.issue = this.issue; 336 target.publishedDateRFC = this.publishedDateRFC; 337 target.publishedYear = this.publishedYear; 338 target.publishedMonth = this.publishedMonth; 339 target.publishedDay = this.publishedDay; 340 target.publishedMonthPadded = this.publishedMonthPadded; 341 target.publishedDayPadded = this.publishedDayPadded; 342 } 343 if (this.updatedDate) { 344 target.updatedDateRFC = this.updatedDateRFC; 345 } 346 target.concatenatedAuthors = this.concatenatedAuthors; 347 target.bibtexAuthors = this.bibtexAuthors; 348 target.slug = this.slug; 349 } 350 351 } 352 353 // Copyright 2018 The Distill Template Authors 354 // 355 // Licensed under the Apache License, Version 2.0 (the "License");
356 // you may not use this file except in compliance with the License. 357 // You may obtain a copy of the License at 358 // 359 // http://www.apache.org/licenses/LICENSE-2.0 360 // 361 // Unless required by applicable law or agreed to in writing, software 362 // distributed under the License is distributed on an "AS IS" BASIS, 363 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 364 // See the License for the specific language governing permissions and 365 // limitations under the License. 366 367 const Mutating = (superclass) => { 368 return class extends superclass { 369 370 constructor() { 371 super(); 372 373 // set up mutation observer 374 const options = {childList: true, characterData: true, subtree: true}; 375 const observer = new MutationObserver( () => { 376 observer.disconnect(); 377 this.renderIfPossible(); 378 observer.observe(this, options); 379 }); 380 381 // ...and listen for changes 382 observer.observe(this, options); 383 } 384 385 connectedCallback() { 386 super.connectedCallback(); 387 388 this.renderIfPossible(); 389 } 390 391 // potential TODO: check if this is enough for all our usecases 392 // maybe provide a custom function to tell if we have enough information to render 393 renderIfPossible() { 394 if (this.textContent && this.root) { 395 this.renderContent(); 396 } 397 } 398 399 renderContent() { 400 console.error(`Your class ${this.constructor.name} must provide a custom renderContent() method!` ); 401 } 402 403 }; // end class 404 }; // end mixin function 405 406 // Copyright 2018 The Distill Template Authors 407 // 408 // Licensed under the Apache License, Version 2.0 (the "License"); 409 // you may not use this file except in compliance with the License. 410 // You may obtain a copy of the License at 411 // 412 // http://www.apache.org/licenses/LICENSE-2.0 413 // 414 // Unless required by applicable law or agreed to in writing, software 415 // distributed under the License is distributed on an "AS IS" BASIS, 416 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 417 // See the License for the specific language governing permissions and 418 // limitations under the License. 419 420 /*global ShadyCSS*/ 421 422 const Template = (name, templateString, useShadow = true) => { 423 424 return (superclass) => { 425 426 const template = document.createElement('template'); 427 template.innerHTML = templateString; 428 429 if (useShadow && 'ShadyCSS' in window) { 430 ShadyCSS.prepareTemplate(template, name); 431 } 432 433 return class extends superclass { 434 435 static get is() { return name; } 436 437 constructor() { 438 super(); 439 440 this.clone = document.importNode(template.content, true); 441 if (useShadow) { 442 this.attachShadow({mode: 'open'}); 443 this.shadowRoot.appendChild(this.clone); 444 } 445 } 446 447 connectedCallback() { 448 if (this.hasAttribute('distill-prerendered')) { 449 return; 450 } 451 if (useShadow) { 452 if ('ShadyCSS' in window) { 453 ShadyCSS.styleElement(this); 454 } 455 } else { 456 this.insertBefore(this.clone, this.firstChild); 457 } 458 } 459 460 get root() { 461 if (useShadow) { 462 return this.shadowRoot; 463 } else { 464 return this; 465 } 466 } 467 468 /* TODO: Are we using these? Should we even? */ 469 $(query) { 470 return this.root.querySelector(query); 471 } 472 473 $$(query) { 474 return this.root.querySelectorAll(query); 475 } 476 }; 477 }; 478 }; 479 480 var math = "/*\n * Copyright 2018 The Distill Template Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nspan.katex-display {\n text-align: left;\n padding: 8px 0 8px 0;\n margin: 0.5em 0 0.5em 1em;\n}\n\nspan.katex {\n -webkit-font-smoothing: antialiased;\n color: rgba(0, 0, 0, 0.8);\n font-size: 1.18em;\n}\n"; 481 482 // Copyright 2018 The Distill Template Authors 483 // 484 // Licensed under the Apache License, Version 2.0 (the "License");
485 // you may not use this file except in compliance with the License. 486 // You may obtain a copy of the License at 487 // 488 // http://www.apache.org/licenses/LICENSE-2.0 489 // 490 // Unless required by applicable law or agreed to in writing, software 491 // distributed under the License is distributed on an "AS IS" BASIS, 492 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 493 // See the License for the specific language governing permissions and 494 // limitations under the License. 495 496 // This is a straight concatenation of code from KaTeX's contrib folder, 497 // but we aren't using some of their helpers that don't work well outside a browser environment. 498 499 /*global katex */ 500 501 const findEndOfMath = function(delimiter, text, startIndex) { 502 // Adapted from 503 // https://github.com/Khan/perseus/blob/master/src/perseus-markdown.jsx 504 let index = startIndex; 505 let braceLevel = 0; 506 507 const delimLength = delimiter.length; 508 509 while (index < text.length) { 510 const character = text[index]; 511 512 if ( 513 braceLevel <= 0 && 514 text.slice(index, index + delimLength) === delimiter 515 ) { 516 return index; 517 } else if (character === "\\") { 518 index++; 519 } else if (character === "{") { 520 braceLevel++; 521 } else if (character === "}") { 522 braceLevel--; 523 } 524 525 index++; 526 } 527 528 return -1; 529 }; 530 531 const splitAtDelimiters = function(startData, leftDelim, rightDelim, display) { 532 const finalData = []; 533 534 for (let i = 0; i < startData.length; i++) { 535 if (startData[i].type === "text") { 536 const text = startData[i].data; 537 538 let lookingForLeft = true; 539 let currIndex = 0; 540 let nextIndex; 541 542 nextIndex = text.indexOf(leftDelim); 543 if (nextIndex !== -1) { 544 currIndex = nextIndex; 545 finalData.push({ 546 type: "text", 547 data: text.slice(0, currIndex) 548 }); 549 lookingForLeft = false; 550 } 551 552 while (true) { 553 // eslint-disable-line no-constant-condition 554 if (lookingForLeft) { 555 nextIndex = text.indexOf(leftDelim, currIndex); 556 if (nextIndex === -1) { 557 break; 558 } 559 560 finalData.push({ 561 type: "text", 562 data: text.slice(currIndex, nextIndex) 563 }); 564 565 currIndex = nextIndex; 566 } else { 567 nextIndex = findEndOfMath( 568 rightDelim, 569 text, 570 currIndex + leftDelim.length 571 ); 572 if (nextIndex === -1) { 573 break; 574 } 575 576 finalData.push({ 577 type: "math", 578 data: text.slice(currIndex + leftDelim.length, nextIndex), 579 rawData: text.slice(currIndex, nextIndex + rightDelim.length), 580 display: display 581 }); 582 583 currIndex = nextIndex + rightDelim.length; 584 } 585 586 lookingForLeft = !lookingForLeft; 587 } 588 589 finalData.push({ 590 type: "text", 591 data: text.slice(currIndex) 592 }); 593 } else { 594 finalData.push(startData[i]); 595 } 596 } 597 598 return finalData; 599 }; 600 601 const splitWithDelimiters = function(text, delimiters) { 602 let data = [{ type: "text", data: text }]; 603 for (let i = 0; i < delimiters.length; i++) { 604 const delimiter = delimiters[i]; 605 data = splitAtDelimiters( 606 data, 607 delimiter.left, 608 delimiter.right, 609 delimiter.display || false 610 ); 611 } 612 return data; 613 }; 614 615 /* Note: optionsCopy is mutated by this method. If it is ever exposed in the 616 * API, we should copy it before mutating. 617 */ 618 const renderMathInText = function(text, optionsCopy) { 619 const data = splitWithDelimiters(text, optionsCopy.delimiters); 620 const fragment = document.createDocumentFragment(); 621 622 for (let i = 0; i < data.length; i++) { 623 if (data[i].type === "text") { 624 fragment.appendChild(document.createTextNode(data[i].data)); 625 } else { 626 const tag = document.createElement("d-math"); 627 const math = data[i].data; 628 // Override any display mode defined in the settings with that 629 // defined by the text itself 630 optionsCopy.displayMode = data[i].display; 631 try { 632 tag.textContent = math; 633 if (optionsCopy.displayMode) { 634 tag.setAttribute("block", ""); 635 } 636 } catch (e) { 637 if (!(e instanceof katex.ParseError)) { 638 throw e; 639 } 640 optionsCopy.errorCallback( 641 "KaTeX auto-render: Failed to parse `" + data[i].data + "` with ", 642 e 643 ); 644 fragment.appendChild(document.createTextNode(data[i].rawData)); 645 continue; 646 } 647 fragment.appendChild(tag); 648 } 649 } 650 651 return fragment; 652 }; 653 654 const renderElem = function(elem, optionsCopy) { 655 for (let i = 0; i < elem.childNodes.length; i++) { 656 const childNode = elem.childNodes[i]; 657 if (childNode.nodeType === 3) { 658 // Text node 659 const text = childNode.textContent; 660 if (optionsCopy.mightHaveMath(text)) { 661 const frag = renderMathInText(text, optionsCopy); 662 i += frag.childNodes.length - 1; 663 elem.replaceChild(frag, childNode); 664 } 665 } else if (childNode.nodeType === 1) { 666 // Element node 667 const shouldRender = 668 optionsCopy.ignoredTags.indexOf(childNode.nodeName.toLowerCase()) === 669 -1; 670 671 if (shouldRender) { 672 renderElem(childNode, optionsCopy); 673 } 674 } 675 // Otherwise, it's something else, and ignore it. 676 } 677 }; 678 679 const defaultAutoRenderOptions = { 680 delimiters: [
681 { left: "$$", right: "$$", display: true }, 682 { left: "\\[", right: "\\]", display: true }, 683 { left: "\\(", right: "\\)", display: false } 684 // LaTeX uses this, but it ruins the display of normal `$` in text: 685 // {left: '$', right: '$', display: false}, 686 ], 687 688 ignoredTags: [ 689 "script", 690 "noscript", 691 "style", 692 "textarea", 693 "pre", 694 "code", 695 "svg" 696 ], 697 698 errorCallback: function(msg, err) { 699 console.error(msg, err); 700 } 701 }; 702 703 const renderMathInElement = function(elem, options) { 704 if (!elem) { 705 throw new Error("No element provided to render"); 706 } 707 708 const optionsCopy = Object.assign({}, defaultAutoRenderOptions, options); 709 const delimiterStrings = optionsCopy.delimiters.flatMap(d => [ 710 d.left, 711 d.right 712 ]); 713 const mightHaveMath = text => 714 delimiterStrings.some(d => text.indexOf(d) !== -1); 715 optionsCopy.mightHaveMath = mightHaveMath; 716 renderElem(elem, optionsCopy); 717 }; 718 719 // Copyright 2018 The Distill Template Authors 720 721 const katexJSURL = 'https://distill.pub/third-party/katex/katex.min.js'; 722 const katexCSSTag = '<link rel="stylesheet" href="https://distill.pub/third-party/katex/katex.min.css" crossorigin="anonymous">'; 723 724 const T = Template('d-math', ` 725${katexCSSTag} 726<style> 727 728:host { 729 display: inline-block; 730 contain: style; 731} 732 733:host([block]) { 734 display: block; 735} 736 737${math} 738</style> 739<span id='katex-container'></span> 740`); 741 742 // DMath, not Math, because that would conflict with the JS built-in 743 class DMath extends Mutating(T(HTMLElement)) { 744 745 static set katexOptions(options) { 746 DMath._katexOptions = options; 747 if (DMath.katexOptions.delimiters) { 748 if (!DMath.katexAdded) { 749 DMath.addKatex(); 750 } else { 751 DMath.katexLoadedCallback(); 752 } 753 } 754 } 755 756 static get katexOptions() { 757 if (!DMath._katexOptions) { 758 DMath._katexOptions = { 759 delimiters: [ { 'left':'$$', 'right':'$$', 'display': false } ] 760 }; 761 } 762 return DMath._katexOptions; 763 } 764 765 static katexLoadedCallback() { 766 // render all d-math tags 767 const mathTags = document.querySelectorAll('d-math'); 768 for (const mathTag of mathTags) { 769 mathTag.renderContent(); 770 } 771 // transform inline delimited math to d-math tags 772 if (DMath.katexOptions.delimiters) { 773 renderMathInElement(document.body, DMath.katexOptions); 774 } 775 } 776 777 static addKatex() { 778 // css tag can use this convenience function 779 document.head.insertAdjacentHTML('beforeend', katexCSSTag); 780 // script tag has to be created to work properly 781 const scriptTag = document.createElement('script'); 782 scriptTag.src = katexJSURL; 783 scriptTag.async = true; 784 scriptTag.onload = DMath.katexLoadedCallback; 785 scriptTag.crossorigin = 'anonymous'; 786 document.head.appendChild(scriptTag); 787 788 DMath.katexAdded = true; 789 } 790 791 get options() { 792 const localOptions = { displayMode: this.hasAttribute('block') }; 793 return Object.assign(localOptions, DMath.katexOptions); 794 } 795 796 connectedCallback() { 797 super.connectedCallback(); 798 if (!DMath.katexAdded) { 799 DMath.addKatex(); 800 } 801 } 802 803 renderContent() { 804 if (typeof katex !== 'undefined') { 805 const container = this.root.querySelector('#katex-container'); 806 katex.render(this.textContent, container, this.options); 807 } 808 } 809 810 } 811 812 DMath.katexAdded = false; 813 DMath.inlineMathRendered = false; 814 window.DMath = DMath; // TODO: check if this can be removed, or if we should expose a distill global 815 816 // Copyright 2018 The Distill Template Authors 817 // 818 // Licensed under the Apache License, Version 2.0 (the "License"); 819 // you may not use this file except in compliance with the License. 820 // You may obtain a copy of the License at 821 // 822 // http://www.apache.org/licenses/LICENSE-2.0 823 // 824 // Unless required by applicable law or agreed to in writing, software 825 // distributed under the License is distributed on an "AS IS" BASIS, 826 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 827 // See the License for the specific language governing permissions and 828 // limitations under the License. 829 830 function collect_citations(dom = document) { 831 const citations = new Set(); 832 const citeTags = dom.querySelectorAll("d-cite"); 833 for (const tag of citeTags) {
834 const keyString = tag.getAttribute("key") || tag.getAttribute("bibtex-key"); 835 const keys = keyString.split(",").map(k => k.trim()); 836 for (const key of keys) { 837 citations.add(key); 838 } 839 } 840 return [...citations]; 841 } 842 843 function author_string(ent, template, sep, finalSep) { 844 if (ent.author == null) { 845 return ""; 846 } 847 var names = ent.author.split(" and "); 848 let name_strings = names.map(name => { 849 name = name.trim(); 850 if (name.indexOf(",") != -1) { 851 var last = name.split(",")[0].trim(); 852 var firsts = name.split(",")[1]; 853 } else if (name.indexOf(" ") != -1) { 854 var last = name 855 .split(" ") 856 .slice(-1)[0] 857 .trim(); 858 var firsts = name 859 .split(" ") 860 .slice(0, -1) 861 .join(" "); 862 } else { 863 var last = name.trim(); 864 } 865 var initials = ""; 866 if (firsts != undefined) { 867 initials = firsts 868 .trim() 869 .split(" ") 870 .map(s => s.trim()[0]); 871 initials = initials.join(".") + "."; 872 } 873 return template 874 .replace("${F}", firsts) 875 .replace("${L}", last) 876 .replace("${I}", initials) 877 .trim(); // in case one of first or last was empty 878 }); 879 if (names.length > 1) { 880 var str = name_strings.slice(0, names.length - 1).join(sep); 881 str += (finalSep || sep) + name_strings[names.length - 1]; 882 return str; 883 } else { 884 return name_strings[0]; 885 } 886 } 887 888 function venue_string(ent) { 889 var cite = ent.journal || ent.booktitle || ""; 890 if ("volume" in ent) { 891 var issue = ent.issue || ent.number; 892 issue = issue != undefined ? "(" + issue + ")" : ""; 893 cite += ", Vol " + ent.volume + issue; 894 } 895 if ("pages" in ent) { 896 cite += ", pp. " + ent.pages; 897 } 898 if (cite != "") cite += ". "; 899 if ("publisher" in ent) { 900 cite += ent.publisher; 901 if (cite[cite.length - 1] != ".") cite += "."; 902 } 903 return cite; 904 } 905 906 function link_string(ent) { 907 if ("url" in ent) { 908 var url = ent.url; 909 var arxiv_match = /arxiv\.org\/abs\/([0-9\.]*)/.exec(url); 910 if (arxiv_match != null) { 911 url = `http://arxiv.org/pdf/${arxiv_match[1]}.pdf`; 912 } 913 914 if (url.slice(-4) == ".pdf") { 915 var label = "PDF"; 916 } else if (url.slice(-5) == ".html") { 917 var label = "HTML"; 918 } 919 return `  <a href="${url}">[${label || "link"}]</a>`; 920 } /* else if ("doi" in ent){ 921 return `  <a href="https://doi.org/${ent.doi}" >[DOI]</a>`; 922 }*/ else { 923 return ""; 924 } 925 } 926 function doi_string(ent, new_line) { 927 if ("doi" in ent) { 928 return `${new_line ? "<br>" : ""} <a href="https://doi.org/${ 929 ent.doi 930 }" style="text-decoration:inherit;">DOI: ${ent.doi}</a>`; 931 } else { 932 return ""; 933 } 934 } 935 936 function title_string(ent) { 937 return '<span class="title">' + ent.title + "</span> "; 938 } 939 940 function bibliography_cite(ent, fancy) { 941 if (ent) { 942 var cite = title_string(ent); 943 cite += link_string(ent) + "<br>"; 944 if (ent.author) { 945 cite += author_string(ent, "${L}, ${I}", ", ", " and "); 946 if (ent.year || ent.date) { 947 cite += ", "; 948 } 949 } 950 if (ent.year || ent.date) { 951 cite += (ent.year || ent.date) + ". "; 952 } else { 953 cite += ". "; 954 } 955 cite += venue_string(ent); 956 cite += doi_string(ent); 957 return cite; 958 /*var cite = author_string(ent, "${L}, ${I}", ", ", " and "); 959 if (ent.year || ent.date){ 960 cite += ", " + (ent.year || ent.date) + ". " 961 } else { 962 cite += ". " 963 } 964 cite += "<b>" + ent.title + "</b>. "; 965 cite += venue_string(ent); 966 cite += doi_string(ent); 967 cite += link_string(ent); 968 return cite*/ 969 } else { 970 return "?"; 971 } 972 } 973 974 function hover_cite(ent) { 975 if (ent) { 976 var cite = ""; 977 cite += "<strong>" + ent.title + "</strong>"; 978 cite += link_string(ent); 979 cite += "<br>"; 980 981 var a_str = author_string(ent, "${I} ${L}", ", ") + "."; 982 var v_str = 983 venue_string(ent).trim() + " " + ent.year + ". " + doi_string(ent, true); 984 985 if ((a_str + v_str).length < Math.min(40, ent.title.length)) {
986 cite += a_str + " " + v_str; 987 } else { 988 cite += a_str + "<br>" + v_str; 989 } 990 return cite; 991 } else { 992 return "?"; 993 } 994 } 995 996 function domContentLoaded() { 997 return ['interactive', 'complete'].indexOf(document.readyState) !== -1; 998 } 999 1000 // Copyright 2018 The Distill Template Authors 1001 // 1002 // Licensed under the Apache License, Version 2.0 (the "License"); 1003 // you may not use this file except in compliance with the License. 1004 // You may obtain a copy of the License at 1005 // 1006 // http://www.apache.org/licenses/LICENSE-2.0 1007 // 1008 // Unless required by applicable law or agreed to in writing, software 1009 // distributed under the License is distributed on an "AS IS" BASIS, 1010 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1011 // See the License for the specific language governing permissions and 1012 // limitations under the License. 1013 1014 function _moveLegacyAffiliationFormatIntoArray(frontMatter) { 1015 // authors used to have propoerties "affiliation" and "affiliationURL". 1016 // We now encourage using an array for affiliations containing objects with 1017 // properties "name" and "url". 1018 for (let author of frontMatter.authors) { 1019 const hasOldStyle = Boolean(author.affiliation); 1020 const hasNewStyle = Boolean(author.affiliations); 1021 if (!hasOldStyle) continue; 1022 if (hasNewStyle) { 1023 console.warn(`Author ${author.author} has both old-style ("affiliation" & "affiliationURL") and new style ("affiliations") affiliation information!`); 1024 } else { 1025 let newAffiliation = { 1026 "name": author.affiliation 1027 }; 1028 if (author.affiliationURL) newAffiliation.url = author.affiliationURL; 1029 author.affiliations = [newAffiliation]; 1030 } 1031 } 1032 return frontMatter 1033 } 1034 1035 function parseFrontmatter(element) { 1036 const scriptTag = element.firstElementChild; 1037 if (scriptTag) { 1038 const type = scriptTag.getAttribute('type'); 1039 if (type.split('/')[1] == 'json') { 1040 const content = scriptTag.textContent; 1041 const parsed = JSON.parse(content); 1042 return _moveLegacyAffiliationFormatIntoArray(parsed); 1043 } else { 1044 console.error('Distill only supports JSON frontmatter tags anymore; no more YAML.'); 1045 } 1046 } else { 1047 console.error('You added a frontmatter tag but did not provide a script tag with front matter data in it. Please take a look at our templates.'); 1048 } 1049 return {}; 1050 } 1051 1052 class FrontMatter$1 extends HTMLElement { 1053 1054 static get is() { return 'd-front-matter'; } 1055 1056 constructor() { 1057 super(); 1058 1059 const options = {childList: true, characterData: true, subtree: true}; 1060 const observer = new MutationObserver( (entries) => { 1061 for (const entry of entries) { 1062 if (entry.target.nodeName === 'SCRIPT' || entry.type === 'characterData') { 1063 const data = parseFrontmatter(this); 1064 this.notify(data); 1065 } 1066 } 1067 }); 1068 observer.observe(this, options); 1069 } 1070 1071 notify(data) { 1072 const options = { detail: data, bubbles: true }; 1073 const event = new CustomEvent('onFrontMatterChanged', options); 1074 document.dispatchEvent(event); 1075 } 1076 1077 } 1078 1079 // Copyright 2018 The Distill Template Authors 1080 // 1081 // Licensed under the Apache License, Version 2.0 (the "License"); 1082 // you may not use this file except in compliance with the License. 1083 // You may obtain a copy of the License at 1084 // 1085 // http://www.apache.org/licenses/LICENSE-2.0 1086 // 1087 // Unless required by applicable law or agreed to in writing, software 1088 // distributed under the License is distributed on an "AS IS" BASIS, 1089 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1090 // See the License for the specific language governing permissions and 1091 // limitations under the License. 1092 1093 // no appendix -> add appendix 1094 // title in front, no h1 -> add it 1095 // no title in front, h1 -> read and put into frontMatter 1096 // footnote -> footnote list 1097 // break up bib 1098 // if citation, no bib-list -> add citation-list 1099 1100 // if authors, no byline -> add byline 1101 1102 function optionalComponents(dom, data) { 1103 const body = dom.body; 1104 const article = body.querySelector('d-article'); 1105 1106 // If we don't have an article tag, something weird is going onâgiving up. 1107 if (!article) { 1108 console.warn('No d-article tag found; skipping adding optional components!'); 1109 return; 1110 } 1111 1112 let byline = dom.querySelector('d-byline'); 1113 if (!byline) { 1114 if (data.authors) { 1115 byline = dom.createElement('d-byline'); 1116 body.insertBefore(byline, article); 1117 } else { 1118 console.warn('No authors found in front matter; please add them before submission!'); 1119 } 1120 } 1121 1122 // let title = dom.querySelector('d-title'); 1123 // if (!title) { 1124 // title = dom.createElement('d-title'); 1125 // body.insertBefore(title, byline); 1126 // } 1127 1128 // let h1 = title.querySelector('h1'); 1129 // if (!h1) { 1130 // h1 = dom.createElement('h1'); 1131 // h1.textContent = data.title; 1132 // title.insertBefore(h1, title.firstChild); 1133 // } 1134 1135 const hasPassword = typeof data.password !== 'undefined'; 1136 let interstitial = body.querySelector('d-interstitial'); 1137 if (hasPassword && !interstitial) { 1138 const inBrowser = typeof window !== 'undefined'; 1139 const onLocalhost = inBrowser && window.location.hostname.includes('localhost'); 1140 if (!inBrowser || !onLocalhost) { 1141 interstitial = dom.createElement('d-interstitial'); 1142 interstitial.password = data.password; 1143 body.insertBefore(interstitial, body.firstChild); 1144 } 1145 } else if (!hasPassword && interstitial) { 1146 interstitial.parentElement.removeChild(this); 1147 } 1148 1149 let appendix = dom.querySelector('d-appendix'); 1150 if (!appendix) { 1151 appendix = dom.createElement('d-appendix'); 1152 dom.body.appendChild(appendix); 1153 } 1154 1155 let footnoteList = dom.querySelector('d-footnote-list'); 1156 if (!footnoteList) { 1157 footnoteList = dom.createElement('d-footnote-list'); 1158 appendix.appendChild(footnoteList); 1159 } 1160
1161 let citationList = dom.querySelector('d-citation-list'); 1162 if (!citationList) { 1163 citationList = dom.createElement('d-citation-list'); 1164 appendix.appendChild(citationList); 1165 } 1166 1167 } 1168 1169 // Copyright 2018 The Distill Template Authors 1170 1171 const frontMatter = new FrontMatter(); 1172 1173 const Controller = { 1174 frontMatter: frontMatter, 1175 waitingOn: { 1176 bibliography: [], 1177 citations: [] 1178 }, 1179 listeners: { 1180 onCiteKeyCreated(event) { 1181 const [citeTag, keys] = event.detail; 1182 1183 // ensure we have citations 1184 if (!frontMatter.citationsCollected) { 1185 // console.debug('onCiteKeyCreated, but unresolved dependency ("citations"). Enqueing.'); 1186 Controller.waitingOn.citations.push(() => 1187 Controller.listeners.onCiteKeyCreated(event) 1188 ); 1189 return; 1190 } 1191 1192 // ensure we have a loaded bibliography 1193 if (!frontMatter.bibliographyParsed) { 1194 // console.debug('onCiteKeyCreated, but unresolved dependency ("bibliography"). Enqueing.'); 1195 Controller.waitingOn.bibliography.push(() => 1196 Controller.listeners.onCiteKeyCreated(event) 1197 ); 1198 return; 1199 } 1200 1201 const numbers = keys.map(key => frontMatter.citations.indexOf(key)); 1202 citeTag.numbers = numbers; 1203 const entries = keys.map(key => frontMatter.bibliography.get(key)); 1204 citeTag.entries = entries; 1205 }, 1206 1207 onCiteKeyChanged() { 1208 // const [citeTag, keys] = event.detail; 1209 1210 // update citations 1211 frontMatter.citations = collect_citations(); 1212 frontMatter.citationsCollected = true; 1213 for (const waitingCallback of Controller.waitingOn.citations.slice()) { 1214 waitingCallback(); 1215 } 1216 1217 // update bibliography 1218 const citationListTag = document.querySelector("d-citation-list"); 1219 const bibliographyEntries = new Map( 1220 frontMatter.citations.map(citationKey => { 1221 return [citationKey, frontMatter.bibliography.get(citationKey)]; 1222 }) 1223 ); 1224 citationListTag.citations = bibliographyEntries; 1225 1226 const citeTags = document.querySelectorAll("d-cite"); 1227 for (const citeTag of citeTags) { 1228 console.log(citeTag); 1229 const keys = citeTag.keys; 1230 const numbers = keys.map(key => frontMatter.citations.indexOf(key)); 1231 citeTag.numbers = numbers; 1232 const entries = keys.map(key => frontMatter.bibliography.get(key)); 1233 citeTag.entries = entries; 1234 } 1235 }, 1236 1237 onCiteKeyRemoved(event) { 1238 Controller.listeners.onCiteKeyChanged(event); 1239 }, 1240 1241 onBibliographyChanged(event) { 1242 const citationListTag = document.querySelector("d-citation-list"); 1243 1244 const bibliography = event.detail; 1245 1246 frontMatter.bibliography = bibliography; 1247 frontMatter.bibliographyParsed = true; 1248 for (const waitingCallback of Controller.waitingOn.bibliography.slice()) { 1249 waitingCallback(); 1250 } 1251 1252 // ensure we have citations 1253 if (!frontMatter.citationsCollected) { 1254 Controller.waitingOn.citations.push(function() { 1255 Controller.listeners.onBibliographyChanged({ 1256 target: event.target, 1257 detail: event.detail 1258 }); 1259 }); 1260 return; 1261 } 1262 1263 if (citationListTag.hasAttribute("distill-prerendered")) { 1264 console.debug("Citation list was prerendered; not updating it."); 1265 } else { 1266 const entries = new Map( 1267 frontMatter.citations.map(citationKey => { 1268 return [citationKey, frontMatter.bibliography.get(citationKey)]; 1269 }) 1270 ); 1271 citationListTag.citations = entries; 1272 } 1273 }, 1274 1275 onFootnoteChanged() { 1276 // const footnote = event.detail; 1277 //TODO: optimize to only update current footnote 1278 const footnotesList = document.querySelector("d-footnote-list"); 1279 if (footnotesList) { 1280 const footnotes = document.querySelectorAll("d-footnote"); 1281 footnotesList.footnotes = footnotes; 1282 } 1283 }, 1284 1285 onFrontMatterChanged(event) { 1286 const data = event.detail; 1287 mergeFromYMLFrontmatter(frontMatter, data); 1288 1289 const interstitial = document.querySelector("d-interstitial"); 1290 if (interstitial) { 1291 if (typeof frontMatter.password !== "undefined") { 1292 interstitial.password = frontMatter.password; 1293 } else { 1294 interstitial.parentElement.removeChild(interstitial); 1295 } 1296 } 1297 1298 const prerendered = document.body.hasAttribute("distill-prerendered"); 1299 if (!prerendered && domContentLoaded()) { 1300 optionalComponents(document, frontMatter); 1301 1302 const appendix = document.querySelector("distill-appendix"); 1303 if (appendix) { 1304 appendix.frontMatter = frontMatter; 1305 } 1306 1307 const byline = document.querySelector("d-byline"); 1308 if (byline) { 1309 byline.frontMatter = frontMatter; 1310 } 1311 1312 if (data.katex) { 1313 DMath.katexOptions = data.katex; 1314 } 1315 } 1316 }, 1317 1318 DOMContentLoaded() { 1319 if (Controller.loaded) { 1320 console.warn( 1321 "Controller received DOMContentLoaded but was already loaded!" 1322 ); 1323 return; 1324 } else if (!domContentLoaded()) { 1325 console.warn( 1326 "Controller received DOMContentLoaded at document.readyState: " + 1327 document.readyState + 1328 "!" 1329 ); 1330 return; 1331 } else { 1332 Controller.loaded = true; 1333 console.debug("Runlevel 4: Controller running DOMContentLoaded"); 1334 } 1335 1336 const frontMatterTag = document.querySelector("d-front-matter"); 1337 if (frontMatterTag) { 1338 const data = parseFrontmatter(frontMatterTag); 1339 Controller.listeners.onFrontMatterChanged({ detail: data }); 1340 } 1341 1342 // Resolving "citations" dependency due to initial DOM load 1343 frontMatter.citations = collect_citations(); 1344 frontMatter.citationsCollected = true; 1345 for (const waitingCallback of Controller.waitingOn.citations.slice()) { 1346 waitingCallback(); 1347 } 1348 1349 if (frontMatter.bibliographyParsed) { 1350 for (const waitingCallback of Controller.waitingOn.bibliography.slice()) { 1351 waitingCallback(); 1352 } 1353 } 1354 1355 const footnotesList = document.querySelector("d-footnote-list"); 1356 if (footnotesList) { 1357 const footnotes = document.querySelectorAll("d-footnote"); 1358 footnotesList.footnotes = footnotes; 1359 } 1360 } 1361 } // listeners 1362 }; // Controller 1363 1364 var base = "/*\n * Copyright 2018 The Distill Template Authors\n *\n *
1364Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nhtml {\n font-size: 14px;\n\tline-height: 1.6em;\n /* font-family: \"Libre Franklin\", \"Helvetica Neue\", sans-serif; */\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, Cantarell, \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", Arial, sans-serif;\n /*, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";*/\n text-size-adjust: 100%;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\n\n@media(min-width: 768px) {\n html {\n font-size: 16px;\n }\n}\n\nbody {\n margin: 0;\n}\n\na {\n color: #004276;\n}\n\nfigure {\n margin: 0;\n}\n\ntable {\n\tborder-collapse: collapse;\n\tborder-spacing: 0;\n}\n\ntable th {\n\ttext-align: left;\n}\n\ntable thead {\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n}\n\ntable thead th {\n padding-bottom: 0.5em;\n}\n\ntable tbody :first-child td {\n padding-top: 0.5em;\n}\n\npre {\n overflow: auto;\n max-width: 100%;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1em;\n}\n\nsup, sub {\n vertical-align: baseline;\n position: relative;\n top: -0.4em;\n line-height: 1em;\n}\n\nsub {\n top: 0.4em;\n}\n\n.kicker,\n.marker {\n font-size: 15px;\n font-weight: 600;\n color: rgba(0, 0, 0, 0.5);\n}\n\n\n/* Headline */\n\n@media(min-width: 1024px) {\n d-title h1 span {\n display: block;\n }\n}\n\n/* Figure */\n\nfigure {\n position: relative;\n margin-bottom: 2.5em;\n margin-top: 1.5em;\n}\n\nfigcaption+figure {\n\n}\n\nfigure img {\n width: 100%;\n}\n\nfigure svg text,\nfigure svg tspan {\n}\n\nfigcaption,\n.figcaption {\n color: rgba(0, 0, 0, 0.6);\n font-size: 12px;\n line-height: 1.5em;\n}\n\n@media(min-width: 1024px) {\nfigcaption,\n.figcaption {\n font-size: 13px;\n }\n}\n\nfigure.external img {\n background: white;\n border: 1px solid rgba(0, 0, 0, 0.1);\n box-shadow: 0 1px 8px rgba(0, 0, 0, 0.1);\n padding: 18px;\n box-sizing: border-box;\n}\n\nfigcaption a {\n color: rgba(0, 0, 0, 0.6);\n}\n\nfigcaption b,\nfigcaption strong, {\n font-weight: 600;\n color: rgba(0, 0, 0, 1.0);\n}\n"; 1365 1366 var layout = "/*\n * Copyright 2018 The Distill Template Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@supports not (display: grid) {\n .base-grid,\n distill-header,\n d-title,\n d-abstract,\n d-article,\n d-appendix,\n distill-appendix,\n d-byline,\n d-footnote-list,\n d-citation-list,\n distill-footer {\n display: block;\n padding: 8px;\n }\n}\n\n.base-grid,\ndistill-header,\nd-title,\nd-abstract,\nd-article,\nd-appendix,\ndistill-appendix,\nd-byline,\nd-footnote-list,\nd-citation-list,\ndistill-footer {\n display: grid;\n justify-items: stretch;\n grid-template-columns: [screen-start] 8px [page-start kicker-start text-start gutter-start middle-start] 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr [text-end page-end gutter-end kicker-end middle-end] 8px [screen-end];\n grid-column-gap: 8px;\n}\n\n.grid {\n display: grid;\n grid-column-gap: 8px;\n}\n\n@media(min-width: 768px) {\n .base-grid,\n distill-header,\n d-title,\n d-abstract,\n d-article,\n d-appendix,\n distill-appendix,\n d-byline,\n d-footnote-list,\n d-citation-list,\n distill-footer {\n grid-template-columns: [screen-start] 1fr [page-start kicker-start middle-start text-start] 45px 45px 45px 45px 45px 45px 45px 45px [ kicker-end text-end gutter-start] 45px [middle-end] 45px [page-end gutter-end] 1fr [screen-end];\n grid-column-gap: 16px;\n }\n\n .grid {\n grid-column-gap: 16px;\n }\n}\n\n@media(min-width: 1000px) {\n .base-grid,\n distill-header,\n d-title,\n d-abstract,\n d-article,\n d-appendix,\n distill-appendix,\n d-byline,\n d-footnote-list,\n d-citation-list,\n distill-footer {\n grid-template-columns: [screen-start] 1fr [page-start kicker-start] 50px [middle-start] 50px [text-start kicker-end] 50px 50px 50px 50px 50px 50px 50px 50px [text-end gutter-start] 50px [middle-end] 50px [page-end gutter-end] 1fr [screen-end];\n grid-column-gap: 16px;\n }\n\n .grid {\n grid-column-gap: 16px;\n }\n}\n\n@media(min-width: 1180px) {\n .base-grid,\n distill-header,\n d-title,\n d-abstract,\n d-article,\n d-appendix,\n distill-appendix,\n d-byline,\n d-footnote-list,\n d-citation-list,\n distill-footer {\n grid-template-columns: [screen-start] 1fr [page-start kicker-start] 60px [middle-start] 60px [text-start kicker-end] 60px 60px 60px 60px 60px 60px 60px 60px [text-end gutter-start] 60px [middle-end] 60px [page-end gutter-end] 1fr [screen-end];\n grid-column-gap: 32px;\n }\n\n .grid {\n grid-column-gap: 32px;\n }\n}\n\n\n\n\n.base-grid {\n grid-column: screen;\n}\n\n/* .l-body,\nd-article > * {\n grid-column: text;\n}\n\n.l-page,\nd-title > *,\nd-figure {\n grid-column: page;\n} */\n\n.l-gutter {\n grid-column: gutter;\n}\n\n.l-text,\n.l-body {\n grid-column: text;\n}\n\n.l-page {\n grid-column: page;\n}\n\n.l-body-outset {\n grid-column: middle;\n}\n\n.l-page-outset {\n grid-column: page;\n}\n\n.l-screen {\n grid-column: screen;\n}\n\n.l-screen-inset {\n grid-column: screen;\n padding-left: 16px;\n padding-left: 16px;\n}\n\n\n/* Aside */\n\nd-article aside {\n grid-column: gutter;\n font-size: 12px;\n line-height: 1.6em;\n color: rgba(0, 0, 0, 0.6)\n}\n\n@media(min-width: 768px) {\n aside {\n grid-column: gutter;\n }\n\n .side {\n grid-column: gutter;\n }\n}\n"; 1367 1368 var print = "/*\n * Copyright 2018 The Distill Template Authors\n *\n *
1368Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@media print {\n\n @page {\n size: 8in 11in;\n @bottom-right {\n content: counter(page) \" of \" counter(pages);\n }\n }\n\n html {\n /* no general margins -- CSS Grid takes care of those */\n }\n\n p, code {\n page-break-inside: avoid;\n }\n\n h2, h3 {\n page-break-after: avoid;\n }\n\n d-header {\n visibility: hidden;\n }\n\n d-footer {\n display: none!important;\n }\n\n}\n"; 1369 1370 var byline = "/*\n * Copyright 2018 The Distill Template Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nd-byline {\n contain: style;\n overflow: hidden;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n font-size: 0.8rem;\n line-height: 1.8em;\n padding: 1.5rem 0;\n min-height: 1.8em;\n}\n\n\nd-byline .byline {\n grid-template-columns: 1fr 1fr;\n grid-column: text;\n}\n\n@media(min-width: 768px) {\n d-byline .byline {\n grid-template-columns: 1fr 1fr 1fr 1fr;\n }\n}\n\nd-byline .authors-affiliations {\n grid-column-end: span 2;\n grid-template-columns: 1fr 1fr;\n margin-bottom: 1em;\n}\n\n@media(min-width: 768px) {\n d-byline .authors-affiliations {\n margin-bottom: 0;\n }\n}\n\nd-byline h3 {\n font-size: 0.6rem;\n font-weight: 400;\n color: rgba(0, 0, 0, 0.5);\n margin: 0;\n text-transform: uppercase;\n}\n\nd-byline p {\n margin: 0;\n}\n\nd-byline a,\nd-article d-byline a {\n color: rgba(0, 0, 0, 0.8);\n text-decoration: none;\n border-bottom: none;\n}\n\nd-article d-byline a:hover {\n text-decoration: underline;\n border-bottom: none;\n}\n\nd-byline p.author {\n font-weight: 500;\n}\n\nd-byline .affiliations {\n\n}\n"; 1371 1372 var article = "/*\n * Copyright 2018 The Distill Template Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nd-article {\n contain: layout style;\n overflow-x: hidden;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n padding-top: 2rem;\n color: rgba(0, 0, 0, 0.8);\n}\n\nd-article > * {\n grid-column: text;\n}\n\n@media(min-width: 768px) {\n d-article {\n font-size: 16px;\n }\n}\n\n@media(min-width: 1024px) {\n d-article {\n font-size: 1.06rem;\n line-height: 1.7em;\n }\n}\n\n\n/* H2 */\n\n\nd-article .marker {\n text-decoration: none;\n border: none;\n counter-reset: section;\n grid-column: kicker;\n line-height: 1.7em;\n}\n\nd-article .marker:hover {\n border: none;\n}\n\nd-article .marker span {\n padding: 0 3px 4px;\n border-bottom: 1px solid rgba(0, 0, 0, 0.2);\n position: relative;\n top: 4px;\n}\n\nd-article .marker:hover span {\n color: rgba(0, 0, 0, 0.7);\n border-bottom: 1px solid rgba(0, 0, 0, 0.7);\n}\n\nd-article h2 {\n font-weight: 600;\n font-size: 24px;\n line-height: 1.25em;\n margin: 2rem 0 1.5rem 0;\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n padding-bottom: 1rem;\n}\n\n@media(min-width: 1024px) {\n d-article h2 {\n font-size: 36px;\n }\n}\n\n/* H3 */\n\nd-article h3 {\n font-weight: 700;\n font-size: 18px;\n line-height: 1.4em;\n margin-bottom: 1em;\n margin-top: 2em;\n}\n\n@media(min-width: 1024px) {\n d-article h3 {\n font-size: 20px;\n }\n}\n\n/* H4 */\n\nd-article h4 {\n font-weight: 600;\n text-transform: uppercase;\n font-size: 14px;\n line-height: 1.4em;\n}\n\nd-article a {\n color: inherit;\n}\n\nd-article p,\nd-article ul,\nd-article ol,\nd-article blockquote {\n margin-top: 0;\n margin-bottom: 1em;\n margin-left: 0;\n margin-right: 0;\n}\n\nd-article blockquote {\n border-left: 2px solid rgba(0, 0, 0, 0.2);\n padding-left: 2em;\n font-style: italic;\n color: rgba(0, 0, 0, 0.6);\n}\n\nd-article a {\n border-bottom: 1px solid rgba(0, 0, 0, 0.4);\n text-decoration: none;\n}\n\nd-article a:hover {\n border-bottom: 1px solid rgba(0, 0, 0, 0.8);\n}\n\nd-article .link {\n text-decoration: underline;\n cursor: pointer;\n}\n\nd-article ul,\nd-article ol {\n padding-left: 24px;\n}\n\nd-article li {\n margin-bottom: 1em;\n margin-left: 0;\n padding-left: 0;\n}\n\nd-article li:last-child {\n margin-bottom: 0;\n}\n\nd-article pre {\n font-size: 14px;\n margin-bottom: 20px;\n}\n\nd-article hr {\n grid-column: screen;\n width: 100%;\n border: none;\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n margin-top: 60px;\n margin-bottom: 60px;\n}\n\nd-article section {\n margin-top: 60px;\n margin-bottom: 60px;\n}\n\nd-article span.equation-mimic {\n font-family: georgia;\n font-size: 115%;\n font-style: italic;\n}\n\nd-article > d-code,\nd-article section > d-code {\n display: block;\n}\n\nd-article > d-math[block],\nd-article section > d-math[block] {\n display: block;\n}\n\n@media (max-width: 768px) {\n d-article > d-code,\n d-article section > d-code,\n d-article > d-math[block],\n d-article section > d-math[block] {\n overflow-x: scroll;\n -ms-overflow-style: none; // IE 10+\n overflow: -moz-scrollbars-none; // Firefox\n }\n\n d-article > d-code::-webkit-scrollbar,\n d-article section > d-code::-webkit-scrollbar,\n d-article > d-math[block]::-webkit-scrollbar,\n d-article section > d-math[block]::-webkit-scrollbar {\n display: none; // Safari and Chrome\n }\n}\n\nd-article .citation {\n color: #668;\n cursor: pointer;\n}\n\nd-include {\n width: auto;\n display: block;\n}\n\nd-figure {\n contain: layout style;\n}
1372\n\n/* KaTeX */\n\n.katex, .katex-prerendered {\n contain: style;\n display: inline-block;\n}\n\n/* Tables */\n\nd-article table {\n border-collapse: collapse;\n margin-bottom: 1.5rem;\n border-bottom: 1px solid rgba(0, 0, 0, 0.2);\n}\n\nd-article table th {\n border-bottom: 1px solid rgba(0, 0, 0, 0.2);\n}\n\nd-article table td {\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n}\n\nd-article table tr:last-of-type td {\n border-bottom: none;\n}\n\nd-article table th,\nd-article table td {\n font-size: 15px;\n padding: 2px 8px;\n}\n\nd-article table tbody :first-child td {\n padding-top: 2px;\n}\n"; 1373 1374 var title = "/*\n * Copyright 2018 The Distill Template Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nd-title {\n padding: 2rem 0 1.5rem;\n contain: layout style;\n overflow-x: hidden;\n}\n\n@media(min-width: 768px) {\n d-title {\n padding: 4rem 0 1.5rem;\n }\n}\n\nd-title h1 {\n grid-column: text;\n font-size: 40px;\n font-weight: 700;\n line-height: 1.1em;\n margin: 0 0 0.5rem;\n}\n\n@media(min-width: 768px) {\n d-title h1 {\n font-size: 50px;\n }\n}\n\nd-title p {\n font-weight: 300;\n font-size: 1.2rem;\n line-height: 1.55em;\n grid-column: text;\n}\n\nd-title .status {\n margin-top: 0px;\n font-size: 12px;\n color: #009688;\n opacity: 0.8;\n grid-column: kicker;\n}\n\nd-title .status span {\n line-height: 1;\n display: inline-block;\n padding: 6px 0;\n border-bottom: 1px solid #80cbc4;\n font-size: 11px;\n text-transform: uppercase;\n}\n"; 1375 1376 // Copyright 2018 The Distill Template Authors 1377 1378 const styles = base + layout + title + byline + article + math + print; 1379 1380 function makeStyleTag(dom) { 1381 1382 const styleTagId = 'distill-prerendered-styles'; 1383 const prerenderedTag = dom.getElementById(styleTagId); 1384 if (!prerenderedTag) { 1385 const styleTag = dom.createElement('style'); 1386 styleTag.id = styleTagId; 1387 styleTag.type = 'text/css'; 1388 const cssTextTag = dom.createTextNode(styles); 1389 styleTag.appendChild(cssTextTag); 1390 const firstScriptTag = dom.head.querySelector('script'); 1391 dom.head.insertBefore(styleTag, firstScriptTag); 1392 } 1393 1394 } 1395 1396 // Copyright 2018 The Distill Template Authors 1397 // 1398 // Licensed under the Apache License, Version 2.0 (the "License"); 1399 // you may not use this file except in compliance with the License. 1400 // You may obtain a copy of the License at 1401 // 1402 // http://www.apache.org/licenses/LICENSE-2.0 1403 // 1404 // Unless required by applicable law or agreed to in writing, software 1405 // distributed under the License is distributed on an "AS IS" BASIS, 1406 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1407 // See the License for the specific language governing permissions and 1408 // limitations under the License. 1409 1410 function addPolyfill(polyfill, polyfillLoadedCallback) { 1411 console.debug('Runlevel 0: Polyfill required: ' + polyfill.name); 1412 const script = document.createElement('script'); 1413 script.src = polyfill.url; 1414 script.async = false; 1415 if (polyfillLoadedCallback) { 1416 script.onload = function() { polyfillLoadedCallback(polyfill); }; 1417 } 1418 script.onerror = function() { 1419 new Error('Runlevel 0: Polyfills failed to load script ' + polyfill.name); 1420 }; 1421 document.head.appendChild(script); 1422 } 1423 1424 const polyfills = [ 1425 { 1426 name: 'WebComponents', 1427 support: function() { 1428 return 'customElements' in window && 1429 'attachShadow' in Element.prototype && 1430 'getRootNode' in Element.prototype && 1431 'content' in document.createElement('template') && 1432 'Promise' in window && 1433 'from' in Array; 1434 }, 1435 url: 'https://distill.pub/third-party/polyfills/webcomponents-lite.js' 1436 }, {
1437 name: 'IntersectionObserver', 1438 support: function() { 1439 return 'IntersectionObserver' in window && 1440 'IntersectionObserverEntry' in window; 1441 }, 1442 url: 'https://distill.pub/third-party/polyfills/intersection-observer.js' 1443 }, 1444 ]; 1445 1446 class Polyfills { 1447 1448 static browserSupportsAllFeatures() { 1449 return polyfills.every((poly) => poly.support()); 1450 } 1451 1452 static load(callback) { 1453 // Define an intermediate callback that checks if all is loaded. 1454 const polyfillLoaded = function(polyfill) { 1455 polyfill.loaded = true; 1456 console.debug('Runlevel 0: Polyfill has finished loading: ' + polyfill.name); 1457 // console.debug(window[polyfill.name]); 1458 if (Polyfills.neededPolyfills.every((poly) => poly.loaded)) { 1459 console.debug('Runlevel 0: All required polyfills have finished loading.'); 1460 console.debug('Runlevel 0->1.'); 1461 window.distillRunlevel = 1; 1462 callback(); 1463 } 1464 }; 1465 // Add polyfill script tags 1466 for (const polyfill of Polyfills.neededPolyfills) { 1467 addPolyfill(polyfill, polyfillLoaded); 1468 } 1469 } 1470 1471 static get neededPolyfills() { 1472 if (!Polyfills._neededPolyfills) { 1473 Polyfills._neededPolyfills = polyfills.filter((poly) => !poly.support()); 1474 } 1475 return Polyfills._neededPolyfills; 1476 } 1477 } 1478 1479 // Copyright 2018 The Distill Template Authors 1480 // 1481 // Licensed under the Apache License, Version 2.0 (the "License"); 1482 // you may not use this file except in compliance with the License. 1483 // You may obtain a copy of the License at 1484 // 1485 // http://www.apache.org/licenses/LICENSE-2.0 1486 // 1487 // Unless required by applicable law or agreed to in writing, software 1488 // distributed under the License is distributed on an "AS IS" BASIS, 1489 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1490 // See the License for the specific language governing permissions and 1491 // limitations under the License. 1492 1493 // const marginSmall = 16; 1494 // const marginLarge = 3 * marginSmall; 1495 // const margin = marginSmall + marginLarge; 1496 // const gutter = marginSmall; 1497 // const outsetAmount = margin / 2; 1498 // const numCols = 4; 1499 // const numGutters = numCols - 1; 1500 // const columnWidth = (768 - 2 * marginLarge - numGutters * gutter) / numCols; 1501 // 1502 // const screenwidth = 768; 1503 // const pageWidth = screenwidth - 2 * marginLarge; 1504 // const bodyWidth = pageWidth - columnWidth - gutter; 1505 1506 function body(selector) { 1507 return `${selector} { 1508 grid-column: left / text; 1509 } 1510 `; 1511 } 1512 1513 // Copyright 2018 The Distill Template Authors 1514 1515 const T$1 = Template('d-abstract', ` 1516<style> 1517 :host { 1518 font-size: 1.25rem; 1519 line-height: 1.6em; 1520 color: rgba(0, 0, 0, 0.7); 1521 -webkit-font-smoothing: antialiased; 1522 } 1523 1524 ::slotted(p) { 1525 margin-top: 0; 1526 margin-bottom: 1em; 1527 grid-column: text-start / middle-end; 1528 } 1529 ${body('d-abstract')} 1530</style> 1531 1532<slot></slot> 1533`); 1534 1535 class Abstract extends T$1(HTMLElement) { 1536 1537 } 1538 1539 // Copyright 2018 The Distill Template Authors 1540 1541 const T$2 = Template('d-appendix', ` 1542<style> 1543 1544d-appendix { 1545 contain: layout style; 1546 font-size: 0.8em; 1547 line-height: 1.7em; 1548 margin-top: 60px; 1549 margin-bottom: 0; 1550 border-top: 1px solid rgba(0, 0, 0, 0.1); 1551 color: rgba(0,0,0,0.5); 1552 padding-top: 60px; 1553 padding-bottom: 48px; 1554} 1555 1556d-appendix h3 { 1557 grid-column: page-start / text-start; 1558 font-size: 15px; 1559 font-weight: 500; 1560 margin-top: 1em; 1561 margin-bottom: 0; 1562 color: rgba(0,0,0,0.65); 1563} 1564 1565d-appendix h3 + * { 1566 margin-top: 1em; 1567} 1568 1569d-appendix ol { 1570 padding: 0 0 0 15px; 1571} 1572 1573@media (min-width: 768px) { 1574 d-appendix ol { 1575 padding: 0 0 0 30px; 1576 margin-left: -30px; 1577 } 1578} 1579 1580d-appendix li { 1581 margin-bottom: 1em; 1582} 1583 1584d-appendix a { 1585 color: rgba(0, 0, 0, 0.6); 1586} 1587 1588d-appendix > * { 1589 grid-column: text; 1590} 1591 1592d-appendix > d-footnote-list, 1593d-appendix > d-citation-list, 1594d-appendix > distill-appendix { 1595 grid-column: screen; 1596} 1597 1598</style> 1599 1600`, false); 1601 1602 class Appendix extends T$2(HTMLElement) { 1603 1604 } 1605 1606 // Copyright 2018 The Distill Template Authors 1607 // 1608 // Licensed under the Apache License, Version 2.0 (the "License");
1609 // you may not use this file except in compliance with the License. 1610 // You may obtain a copy of the License at 1611 // 1612 // http://www.apache.org/licenses/LICENSE-2.0 1613 // 1614 // Unless required by applicable law or agreed to in writing, software 1615 // distributed under the License is distributed on an "AS IS" BASIS, 1616 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1617 // See the License for the specific language governing permissions and 1618 // limitations under the License. 1619 1620 // import { Template } from '../mixins/template'; 1621 // import { Controller } from '../controller'; 1622 1623 const isOnlyWhitespace = /^\s*$/; 1624 1625 class Article extends HTMLElement { 1626 static get is() { return 'd-article'; } 1627 1628 constructor() { 1629 super(); 1630 1631 new MutationObserver( (mutations) => { 1632 for (const mutation of mutations) { 1633 for (const addedNode of mutation.addedNodes) { 1634 switch (addedNode.nodeName) { 1635 case '#text': { // usually text nodes are only linebreaks. 1636 const text = addedNode.nodeValue; 1637 if (!isOnlyWhitespace.test(text)) { 1638 console.warn('Use of unwrapped text in distill articles is discouraged as it breaks layout! Please wrap any text in a <span> or <p> tag. We found the following text: ' + text); 1639 const wrapper = document.createElement('span'); 1640 wrapper.innerHTML = addedNode.nodeValue; 1641 addedNode.parentNode.insertBefore(wrapper, addedNode); 1642 addedNode.parentNode.removeChild(addedNode); 1643 } 1644 } break; 1645 } 1646 } 1647 } 1648 }).observe(this, {childList: true}); 1649 } 1650 1651 } 1652 1653 var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; 1654 1655 function createCommonjsModule(fn, module) { 1656 return module = { exports: {} }, fn(module, module.exports), module.exports; 1657 } 1658 1659 var bibtexParse = createCommonjsModule(function (module, exports) { 1660 /* start bibtexParse 0.0.22 */ 1661 1662 //Original work by Henrik Muehe (c) 2010 1663 // 1664 //CommonJS port by Mikola Lysenko 2013 1665 // 1666 //Port to Browser lib by ORCID / RCPETERS 1667 // 1668 //Issues: 1669 //no comment handling within strings 1670 //no string concatenation 1671 //no variable values yet 1672 //Grammar implemented here: 1673 //bibtex -> (string | preamble | comment | entry)*; 1674 //string -> '@STRING' '{' key_equals_value '}'; 1675 //preamble -> '@PREAMBLE' '{' value '}'; 1676 //comment -> '@COMMENT' '{' value '}'; 1677 //entry -> '@' key '{' key ',' key_value_list '}'; 1678 //key_value_list -> key_equals_value (',' key_equals_value)*; 1679 //key_equals_value -> key '=' value; 1680 //value -> value_quotes | value_braces | key; 1681 //value_quotes -> '"' .*? '"'; // not quite 1682 //value_braces -> '{' .*? '"'; // not quite 1683 (function(exports) { 1684 1685 function BibtexParser() { 1686 1687 this.months = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"]; 1688 this.notKey = [',','{','}',' ','=']; 1689 this.pos = 0; 1690 this.input = ""; 1691 this.entries = new Array(); 1692 1693 this.currentEntry = ""; 1694 1695 this.setInput = function(t) { 1696 this.input = t; 1697 }; 1698 1699 this.getEntries = function() { 1700 return this.entries; 1701 }; 1702 1703 this.isWhitespace = function(s) { 1704 return (s == ' ' || s == '\r' || s == '\t' || s == '\n'); 1705 }; 1706 1707 this.match = function(s, canCommentOut) { 1708 if (canCommentOut == undefined || canCommentOut == null) 1709 canCommentOut = true; 1710 this.skipWhitespace(canCommentOut); 1711 if (this.input.substring(this.pos, this.pos + s.length) == s) { 1712 this.pos += s.length; 1713 } else { 1714 throw "Token mismatch, expected " + s + ", found " 1715 + this.input.substring(this.pos); 1716 } this.skipWhitespace(canCommentOut); 1717 }; 1718 1719 this.tryMatch = function(s, canCommentOut) { 1720 if (canCommentOut == undefined || canCommentOut == null) 1721 canCommentOut = true; 1722 this.skipWhitespace(canCommentOut); 1723 if (this.input.substring(this.pos, this.pos + s.length) == s) { 1724 return true; 1725 } else { 1726 return false;
1727 } }; 1728 1729 /* when search for a match all text can be ignored, not just white space */ 1730 this.matchAt = function() { 1731 while (this.input.length > this.pos && this.input[this.pos] != '@') { 1732 this.pos++; 1733 } 1734 if (this.input[this.pos] == '@') { 1735 return true; 1736 } return false; 1737 }; 1738 1739 this.skipWhitespace = function(canCommentOut) { 1740 while (this.isWhitespace(this.input[this.pos])) { 1741 this.pos++; 1742 } if (this.input[this.pos] == "%" && canCommentOut == true) { 1743 while (this.input[this.pos] != "\n") { 1744 this.pos++; 1745 } this.skipWhitespace(canCommentOut); 1746 } }; 1747 1748 this.value_braces = function() { 1749 var bracecount = 0; 1750 this.match("{", false); 1751 var start = this.pos; 1752 var escaped = false; 1753 while (true) { 1754 if (!escaped) { 1755 if (this.input[this.pos] == '}') { 1756 if (bracecount > 0) { 1757 bracecount--; 1758 } else { 1759 var end = this.pos; 1760 this.match("}", false); 1761 return this.input.substring(start, end); 1762 } } else if (this.input[this.pos] == '{') { 1763 bracecount++; 1764 } else if (this.pos >= this.input.length - 1) { 1765 throw "Unterminated value"; 1766 } } if (this.input[this.pos] == '\\' && escaped == false) 1767 escaped = true; 1768 else 1769 escaped = false; 1770 this.pos++; 1771 } }; 1772 1773 this.value_comment = function() { 1774 var str = ''; 1775 var brcktCnt = 0; 1776 while (!(this.tryMatch("}", false) && brcktCnt == 0)) { 1777 str = str + this.input[this.pos]; 1778 if (this.input[this.pos] == '{') 1779 brcktCnt++; 1780 if (this.input[this.pos] == '}') 1781 brcktCnt--; 1782 if (this.pos >= this.input.length - 1) { 1783 throw "Unterminated value:" + this.input.substring(start); 1784 } this.pos++; 1785 } return str; 1786 }; 1787 1788 this.value_quotes = function() { 1789 this.match('"', false); 1790 var start = this.pos; 1791 var escaped = false; 1792 while (true) { 1793 if (!escaped) { 1794 if (this.input[this.pos] == '"') { 1795 var end = this.pos; 1796 this.match('"', false); 1797 return this.input.substring(start, end); 1798 } else if (this.pos >= this.input.length - 1) { 1799 throw "Unterminated value:" + this.input.substring(start); 1800 } } 1801 if (this.input[this.pos] == '\\' && escaped == false) 1802 escaped = true; 1803 else 1804 escaped = false; 1805 this.pos++; 1806 } }; 1807 1808 this.single_value = function() { 1809 var start = this.pos; 1810 if (this.tryMatch("{")) { 1811 return this.value_braces(); 1812 } else if (this.tryMatch('"')) { 1813 return this.value_quotes(); 1814 } else { 1815 var k = this.key(); 1816 if (k.match("^[0-9]+$")) 1817 return k; 1818 else if (this.months.indexOf(k.toLowerCase()) >= 0) 1819 return k.toLowerCase(); 1820 else 1821 throw "Value expected:" + this.input.substring(start) + ' for key: ' + k; 1822 1823 } }; 1824 1825 this.value = function() { 1826 var values = [];
1827 values.push(this.single_value()); 1828 while (this.tryMatch("#")) { 1829 this.match("#"); 1830 values.push(this.single_value()); 1831 } return values.join(""); 1832 }; 1833 1834 this.key = function() { 1835 var start = this.pos; 1836 while (true) { 1837 if (this.pos >= this.input.length) { 1838 throw "Runaway key"; 1839 } // а-ÑÐ-Я is Cyrillic 1840 //console.log(this.input[this.pos]); 1841 if (this.notKey.indexOf(this.input[this.pos]) >= 0) { 1842 return this.input.substring(start, this.pos); 1843 } else { 1844 this.pos++; 1845 1846 } } }; 1847 1848 this.key_equals_value = function() { 1849 var key = this.key(); 1850 if (this.tryMatch("=")) { 1851 this.match("="); 1852 var val = this.value(); 1853 return [ key, val ]; 1854 } else { 1855 throw "... = value expected, equals sign missing:" 1856 + this.input.substring(this.pos); 1857 } }; 1858 1859 this.key_value_list = function() { 1860 var kv = this.key_equals_value(); 1861 this.currentEntry['entryTags'] = {}; 1862 this.currentEntry['entryTags'][kv[0]] = kv[1]; 1863 while (this.tryMatch(",")) { 1864 this.match(","); 1865 // fixes problems with commas at the end of a list 1866 if (this.tryMatch("}")) { 1867 break; 1868 } 1869 kv = this.key_equals_value(); 1870 this.currentEntry['entryTags'][kv[0]] = kv[1]; 1871 } }; 1872 1873 this.entry_body = function(d) { 1874 this.currentEntry = {}; 1875 this.currentEntry['citationKey'] = this.key(); 1876 this.currentEntry['entryType'] = d.substring(1); 1877 this.match(","); 1878 this.key_value_list(); 1879 this.entries.push(this.currentEntry); 1880 }; 1881 1882 this.directive = function() { 1883 this.match("@"); 1884 return "@" + this.key(); 1885 }; 1886 1887 this.preamble = function() { 1888 this.currentEntry = {}; 1889 this.currentEntry['entryType'] = 'PREAMBLE'; 1890 this.currentEntry['entry'] = this.value_comment(); 1891 this.entries.push(this.currentEntry); 1892 }; 1893 1894 this.comment = function() { 1895 this.currentEntry = {}; 1896 this.currentEntry['entryType'] = 'COMMENT'; 1897 this.currentEntry['entry'] = this.value_comment(); 1898 this.entries.push(this.currentEntry); 1899 }; 1900 1901 this.entry = function(d) { 1902 this.entry_body(d); 1903 }; 1904 1905 this.bibtex = function() { 1906 while (this.matchAt()) { 1907 var d = this.directive(); 1908 this.match("{"); 1909 if (d == "@STRING") { 1910 this.string(); 1911 } else if (d == "@PREAMBLE") { 1912 this.preamble(); 1913 } else if (d == "@COMMENT") { 1914 this.comment(); 1915 } else { 1916 this.entry(d); 1917 } 1918 this.match("}"); 1919 } }; 1920 } 1921 exports.toJSON = function(bibtex) { 1922 var b = new BibtexParser(); 1923 b.setInput(bibtex); 1924 b.bibtex(); 1925 return b.entries; 1926 }; 1927 1928 /* added during hackathon don't hate on me */ 1929 exports.toBibtex = function(json) { 1930 var out = ''; 1931 for ( var i in json) { 1932 out += "@" + json[i].entryType; 1933 out += '{'; 1934 if (json[i].citationKey) 1935 out += json[i].citationKey + ', '; 1936 if (json[i].entry) 1937 out += json[i].entry ; 1938 if (json[i].entryTags) { 1939 var tags = ''; 1940 for (var jdx in json[i].entryTags) { 1941 if (tags.length != 0) 1942 tags += ', '; 1943 tags += jdx + '= {' + json[i].entryTags[jdx] + '}'; 1944 } 1945 out += tags; 1946 } 1947 out += '}\n\n'; 1948 } 1949 return out; 1950 1951 }; 1952 1953 })( exports); 1954 1955 /* end bibtexParse */ 1956 }); 1957 1958 // Copyright 2018 The Distill Template Authors 1959 1960 function normalizeTag(string) { 1961 return string 1962 .replace(/[\t\n ]+/g, ' ') 1963 .replace(/{\\["^`.'acu~Hvs]( )?([a-zA-Z])}/g, (full, x, char) => char) 1964 .replace(/{\\([a-zA-Z])}/g, (full, char) => char); 1965 } 1966 1967 function parseBibtex(bibtex) { 1968 const bibliography = new Map(); 1969 const parsedEntries = bibtexParse.toJSON(bibtex); 1970 for (const entry of parsedEntries) { 1971 // normalize tags; note entryTags is an object, not Map 1972 for (const [key, value] of Object.entries(entry.entryTags)) { 1973 entry.entryTags[key.toLowerCase()] = normalizeTag(value); 1974 } 1975 entry.entryTags.type = entry.entryType; 1976 // add to bibliography 1977 bibliography.set(entry.citationKey, entry.entryTags); 1978 } 1979 return bibliography; 1980 } 1981 1982 function serializeFrontmatterToBibtex(frontMatter) { 1983 return `@article{${frontMatter.slug}, 1984 author = {${frontMatter.bibtexAuthors}}, 1985 title = {${frontMatter.title}}, 1986 journal = {${frontMatter.journal.title}}, 1987 year = {${frontMatter.publishedYear}}, 1988 note = {${frontMatter.url}}, 1989 doi = {${frontMatter.doi}} 1990}`; 1991 } 1992 1993 // Copyright 2018 The Distill Template Authors 1994 1995 class Bibliography extends HTMLElement { 1996 1997 static get is() { return 'd-bibliography'; } 1998 1999 constructor() { 2000 super(); 2001 2002 // set up mutation observer 2003 const options = {childList: true, characterData: true, subtree: true}; 2004 const observer = new MutationObserver( (entries) => {
2005 for (const entry of entries) { 2006 if (entry.target.nodeName === 'SCRIPT' || entry.type === 'characterData') { 2007 this.parseIfPossible(); 2008 } 2009 } 2010 }); 2011 observer.observe(this, options); 2012 } 2013 2014 connectedCallback() { 2015 requestAnimationFrame(() => { 2016 this.parseIfPossible(); 2017 }); 2018 } 2019 2020 parseIfPossible() { 2021 const scriptTag = this.querySelector('script'); 2022 if (!scriptTag) return; 2023 if (scriptTag.type == 'text/bibtex') { 2024 const newBibtex = scriptTag.textContent; 2025 if (this.bibtex !== newBibtex) { 2026 this.bibtex = newBibtex; 2027 const bibliography = parseBibtex(this.bibtex); 2028 this.notify(bibliography); 2029 } 2030 } else if (scriptTag.type == 'text/json') { 2031 const bibliography = new Map(JSON.parse(scriptTag.textContent)); 2032 this.notify(bibliography); 2033 } else { 2034 console.warn('Unsupported bibliography script tag type: ' + scriptTag.type); 2035 } 2036 } 2037 2038 notify(bibliography) { 2039 const options = { detail: bibliography, bubbles: true }; 2040 const event = new CustomEvent('onBibliographyChanged', options); 2041 this.dispatchEvent(event); 2042 } 2043 2044 /* observe 'src' attribute */ 2045 2046 static get observedAttributes() { 2047 return ['src']; 2048 } 2049 2050 receivedBibtex(event) { 2051 const bibliography = parseBibtex(event.target.response); 2052 this.notify(bibliography); 2053 } 2054 2055 attributeChangedCallback(name, oldValue, newValue) { 2056 var oReq = new XMLHttpRequest(); 2057 oReq.onload = (e) => this.receivedBibtex(e); 2058 oReq.onerror = () => console.warn(`Could not load Bibtex! (tried ${newValue})`); 2059 oReq.responseType = 'text'; 2060 oReq.open('GET', newValue, true); 2061 oReq.send(); 2062 } 2063 2064 2065 } 2066 2067 // Copyright 2018 The Distill Template Authors 2068 // 2069 // Licensed under the Apache License, Version 2.0 (the "License"); 2070 // you may not use this file except in compliance with the License. 2071 // You may obtain a copy of the License at 2072 // 2073 // http://www.apache.org/licenses/LICENSE-2.0 2074 // 2075 // Unless required by applicable law or agreed to in writing, software 2076 // distributed under the License is distributed on an "AS IS" BASIS, 2077 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2078 // See the License for the specific language governing permissions and 2079 // limitations under the License. 2080 2081 // import style from '../styles/d-byline.css'; 2082 2083 function bylineTemplate(frontMatter) { 2084 return ` 2085 <div class="byline grid"> 2086 <div class="authors-affiliations grid"> 2087 <h3>Authors</h3> 2088 <h3>Affiliations</h3> 2089 ${frontMatter.authors.map(author => ` 2090 <p class="author"> 2091 ${author.personalURL ? ` 2092 <a class="name" href="${author.personalURL}">${author.name}</a>` : ` 2093 <span class="name">${author.name}</span>`} 2094 </p> 2095 <p class="affiliation"> 2096 ${author.affiliations.map(affiliation => 2097 affiliation.url ? `<a class="affiliation" href="${affiliation.url}">${affiliation.name}</a>` : `<span class="affiliation">${affiliation.name}</span>` 2098 ).join(', ')} 2099 </p> 2100 `).join('')} 2101 </div> 2102 <div> 2103 <h3>Date</h3> 2104 ${frontMatter.publishedDate ? ` 2105 <p>${frontMatter.publishedMonth} ${frontMatter.publishedDay}, ${frontMatter.publishedYear}</p> ` : ` 2106 <p><em>Not published yet.</em></p>`} 2107 </div> 2108 </div> 2109 `; 2110 } 2111 2112 2113 class Byline extends HTMLElement { 2114 2115 static get is() { return 'd-byline'; } 2116 2117 set frontMatter(frontMatter) { 2118 this.innerHTML = bylineTemplate(frontMatter); 2119 } 2120 2121 } 2122 2123 // Copyright 2018 The Distill Template Authors 2124 2125 const T$3 = Template( 2126 "d-cite", 2127 ` 2128<style> 2129 2130:host { 2131 display: inline-block; 2132} 2133 2134.citation { 2135 color: hsla(206, 90%, 20%, 0.7); 2136} 2137 2138.citation-number {
2139 cursor: default; 2140 white-space: nowrap; 2141 font-family: -apple-system, BlinkMacSystemFont, "Roboto", Helvetica, sans-serif; 2142 font-size: 75%; 2143 color: hsla(206, 90%, 20%, 0.7); 2144 display: inline-block; 2145 line-height: 1.1em; 2146 text-align: center; 2147 position: relative; 2148 top: -2px; 2149 margin: 0 2px; 2150} 2151 2152figcaption .citation-number { 2153 font-size: 11px; 2154 font-weight: normal; 2155 top: -2px; 2156 line-height: 1em; 2157} 2158 2159ul { 2160 margin: 0; 2161 padding: 0; 2162 list-style-type: none; 2163} 2164 2165ul li { 2166 padding: 15px 10px 15px 10px; 2167 border-bottom: 1px solid rgba(0,0,0,0.1) 2168} 2169 2170ul li:last-of-type { 2171 border-bottom: none; 2172} 2173 2174</style> 2175 2176<d-hover-box id="hover-box"></d-hover-box> 2177 2178<div id="citation-" class="citation"> 2179 <span class="citation-number"></span> 2180</div> 2181` 2182 ); 2183 2184 class Cite extends T$3(HTMLElement) { 2185 /* Lifecycle */ 2186 constructor() { 2187 super(); 2188 this._numbers = []; 2189 this._entries = []; 2190 } 2191 2192 connectedCallback() { 2193 this.outerSpan = this.root.querySelector("#citation-"); 2194 this.innerSpan = this.root.querySelector(".citation-number"); 2195 this.hoverBox = this.root.querySelector("d-hover-box"); 2196 window.customElements.whenDefined("d-hover-box").then(() => { 2197 this.hoverBox.listen(this); 2198 }); 2199 // in case this component got connected after values were set 2200 if (this.numbers) { 2201 this.displayNumbers(this.numbers); 2202 } 2203 if (this.entries) { 2204 this.displayEntries(this.entries); 2205 } 2206 } 2207 2208 //TODO This causes an infinite loop on firefox with polyfills. 2209 // This is only needed for interactive editing so no priority. 2210 // disconnectedCallback() { 2211 // const options = { detail: [this, this.keys], bubbles: true }; 2212 // const event = new CustomEvent('onCiteKeyRemoved', options); 2213 // document.dispatchEvent(event); 2214 // } 2215 2216 /* observe 'key' attribute */ 2217 2218 static get observedAttributes() { 2219 return ["key", "bibtex-key"]; 2220 } 2221 2222 attributeChangedCallback(name, oldValue, newValue) { 2223 const eventName = oldValue ? "onCiteKeyChanged" : "onCiteKeyCreated"; 2224 const keys = newValue.split(",").map(k => k.trim()); 2225 const options = { detail: [this, keys], bubbles: true }; 2226 const event = new CustomEvent(eventName, options); 2227 document.dispatchEvent(event); 2228 } 2229 2230 set key(value) { 2231 this.setAttribute("key", value); 2232 } 2233 2234 get key() { 2235 return this.getAttribute("key") || this.getAttribute("bibtex-key"); 2236 } 2237 2238 get keys() { 2239 const result = this.key.split(","); 2240 console.log(result); 2241 return result; 2242 } 2243 2244 /* Setters & Rendering */ 2245 2246 set numbers(numbers) { 2247 this._numbers = numbers; 2248 this.displayNumbers(numbers); 2249 } 2250 2251 get numbers() { 2252 return this._numbers; 2253 } 2254 2255 displayNumbers(numbers) { 2256 if (!this.innerSpan) return; 2257 const numberStrings = numbers.map(index => { 2258 return index == -1 ? "?" : index + 1 + ""; 2259 }); 2260 const textContent = "[" + numberStrings.join(", ") + "]"; 2261 this.innerSpan.textContent = textContent; 2262 } 2263 2264 set entries(entries) { 2265 this._entries = entries; 2266 this.displayEntries(entries); 2267 } 2268 2269 get entries() { 2270 return this._entries; 2271 } 2272 2273 displayEntries(entries) { 2274 if (!this.hoverBox) return; 2275 this.hoverBox.innerHTML = `<ul> 2276 ${entries 2277 .map(hover_cite) 2278 .map(html => `<li>${html}</li>`) 2279 .join("\n")} 2280 </ul>`; 2281 } 2282 } 2283 2284 // Copyright 2018 The Distill Template Authors 2285 2286 const styles$1 = ` 2287d-citation-list { 2288 contain: style; 2289} 2290 2291d-citation-list .references { 2292 grid-column: text; 2293} 2294 2295d-citation-list .references .title { 2296 font-weight: 500; 2297} 2298`; 2299 2300 function renderCitationList(element, entries, dom=document) { 2301 if (entries.size > 0) { 2302 element.style.display = ''; 2303 let list = element.querySelector('.references'); 2304 if (list) { 2305 list.innerHTML = ''; 2306 } else { 2307 const stylesTag = dom.createElement('style'); 2308 stylesTag.innerHTML = styles$1; 2309 element.appendChild(stylesTag); 2310 2311 const heading = dom.createElement('h3'); 2312 heading.id = 'references'; 2313 heading.textContent = 'References'; 2314 element.appendChild(heading); 2315 2316 list = dom.createElement('ol'); 2317 list.id = 'references-list'; 2318 list.className = 'references'; 2319 element.appendChild(list); 2320 } 2321
2322 for (const [key, entry] of entries) { 2323 const listItem = dom.createElement('li'); 2324 listItem.id = key; 2325 listItem.innerHTML = bibliography_cite(entry); 2326 list.appendChild(listItem); 2327 } 2328 } else { 2329 element.style.display = 'none'; 2330 } 2331 } 2332 2333 class CitationList extends HTMLElement { 2334 2335 static get is() { return 'd-citation-list'; } 2336 2337 connectedCallback() { 2338 if (!this.hasAttribute('distill-prerendered')) { 2339 this.style.display = 'none'; 2340 } 2341 } 2342 2343 set citations(citations) { 2344 renderCitationList(this, citations); 2345 } 2346 2347 } 2348 2349 var prism = createCommonjsModule(function (module) { 2350 /* ********************************************** 2351 Begin prism-core.js 2352 ********************************************** */ 2353 2354 var _self = (typeof window !== 'undefined') 2355 ? window // if in browser 2356 : ( 2357 (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) 2358 ? self // if in worker 2359 : {} // if in node js 2360 ); 2361 2362 /** 2363 * Prism: Lightweight, robust, elegant syntax highlighting 2364 * MIT license http://www.opensource.org/licenses/mit-license.php/ 2365 * @author Lea Verou http://lea.verou.me 2366 */ 2367 2368 var Prism = (function (_self){ 2369 2370 // Private helper vars 2371 var lang = /\blang(?:uage)?-([\w-]+)\b/i; 2372 var uniqueId = 0; 2373 2374 2375 var _ = { 2376 manual: _self.Prism && _self.Prism.manual, 2377 disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler, 2378 util: { 2379 encode: function encode(tokens) { 2380 if (tokens instanceof Token) { 2381 return new Token(tokens.type, encode(tokens.content), tokens.alias); 2382 } else if (Array.isArray(tokens)) { 2383 return tokens.map(encode); 2384 } else { 2385 return tokens.replace(/&/g, '&').replace(/</g, '<').replace(/\u00a0/g, ' '); 2386 } 2387 }, 2388 2389 type: function (o) { 2390 return Object.prototype.toString.call(o).slice(8, -1); 2391 }, 2392 2393 objId: function (obj) { 2394 if (!obj['__id']) { 2395 Object.defineProperty(obj, '__id', { value: ++uniqueId }); 2396 } 2397 return obj['__id']; 2398 }, 2399 2400 // Deep clone a language definition (e.g. to extend it) 2401 clone: function deepClone(o, visited) { 2402 var clone, id, type = _.util.type(o); 2403 visited = visited || {}; 2404 2405 switch (type) { 2406 case 'Object': 2407 id = _.util.objId(o); 2408 if (visited[id]) { 2409 return visited[id]; 2410 } 2411 clone = {}; 2412 visited[id] = clone; 2413 2414 for (var key in o) { 2415 if (o.hasOwnProperty(key)) { 2416 clone[key] = deepClone(o[key], visited); 2417 } 2418 } 2419 2420 return clone; 2421 2422 case 'Array': 2423 id = _.util.objId(o); 2424 if (visited[id]) { 2425 return visited[id]; 2426 } 2427 clone = []; 2428 visited[id] = clone; 2429 2430 o.forEach(function (v, i) { 2431 clone[i] = deepClone(v, visited); 2432 }); 2433 2434 return clone; 2435 2436 default: 2437 return o; 2438 } 2439 }, 2440 2441 /** 2442 * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class. 2443 * 2444 * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned. 2445 * 2446 * @param {Element} element 2447 * @returns {string} 2448 */ 2449 getLanguage: function (element) { 2450 while (element && !lang.test(element.className)) { 2451 element = element.parentElement; 2452 } 2453 if (element) { 2454 return (element.className.match(lang) || [, 'none'])[1].toLowerCase(); 2455 } 2456 return 'none'; 2457 }, 2458 2459 /** 2460 * Returns the script element that is currently executing. 2461 * 2462 * This does __not__ work for line script element. 2463 * 2464 * @returns {HTMLScriptElement | null} 2465 */ 2466 currentScript: function () { 2467 if (typeof document === 'undefined') { 2468 return null; 2469 } 2470 if ('currentScript' in document) { 2471 return document.currentScript; 2472 } 2473 2474 // IE11 workaround 2475 // we'll get the src of the current script by parsing IE11's error stack trace 2476 // this will not work for inline scripts 2477 2478 try { 2479 throw new Error(); 2480 } catch (err) { 2481 // Get file src url from stack. Specifically works with the format of stack traces in IE. 2482 // A stack will look like this: 2483 // 2484 // Error 2485 // at _.util.currentScript (http://localhost/components/prism-core.js:119:5) 2486 // at Global code (http://localhost/components/prism-core.js:606:1) 2487 2488 var src = (/at [^(\r\n]*\((.*):.+:.+\)$/i.exec(err.stack) || [])[1]; 2489 if (src) { 2490 var scripts = document.getElementsByTagName('script'); 2491 for (var i in scripts) { 2492 if (scripts[i].src == src) { 2493 return scripts[i]; 2494 } 2495 } 2496 } 2497 return null; 2498 } 2499 } 2500 }, 2501 2502 languages: { 2503 extend: function (id, redef) { 2504 var lang = _.util.clone(_.languages[id]); 2505 2506 for (var key in redef) { 2507 lang[key] = redef[key]; 2508 } 2509 2510 return lang; 2511 }, 2512 2513 /** 2514 * Insert a token before another token in a language literal 2515 * As this needs to recreate the object (we cannot actually insert before keys in object literals), 2516 * we cannot just provide an object, we need an object and a key. 2517 * @param inside The key (or language id) of the parent 2518 * @param before The key to insert before. 2519 * @param insert Object with the key/value pairs to insert 2520 * @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted. 2521 */ 2522 insertBefore: function (inside, before, insert, root) { 2523 root = root || _.languages; 2524 var grammar = root[inside]; 2525 var ret = {}; 2526 2527 for (var token in grammar) { 2528 if (grammar.hasOwnProperty(token)) { 2529 2530 if (token == before) { 2531 for (var newToken in insert) { 2532 if (insert.hasOwnProperty(newToken)) { 2533 ret[newToken] = insert[newToken]; 2534 } 2535 } 2536 } 2537
vendor: 5,588 bytes, lines 2538-2766
2538 // Do not insert token which also occur in insert. See #1525 2539 if (!insert.hasOwnProperty(token)) { 2540 ret[token] = grammar[token]; 2541 } 2542 } 2543 } 2544 2545 var old = root[inside]; 2546 root[inside] = ret; 2547 2548 // Update references in other language definitions 2549 _.languages.DFS(_.languages, function(key, value) { 2550 if (value === old && key != inside) { 2551 this[key] = ret; 2552 } 2553 }); 2554 2555 return ret; 2556 }, 2557 2558 // Traverse a language definition with Depth First Search 2559 DFS: function DFS(o, callback, type, visited) { 2560 visited = visited || {}; 2561 2562 var objId = _.util.objId; 2563 2564 for (var i in o) { 2565 if (o.hasOwnProperty(i)) { 2566 callback.call(o, i, o[i], type || i); 2567 2568 var property = o[i], 2569 propertyType = _.util.type(property); 2570 2571 if (propertyType === 'Object' && !visited[objId(property)]) { 2572 visited[objId(property)] = true; 2573 DFS(property, callback, null, visited); 2574 } 2575 else if (propertyType === 'Array' && !visited[objId(property)]) { 2576 visited[objId(property)] = true; 2577 DFS(property, callback, i, visited); 2578 } 2579 } 2580 } 2581 } 2582 }, 2583 plugins: {}, 2584 2585 highlightAll: function(async, callback) { 2586 _.highlightAllUnder(document, async, callback); 2587 }, 2588 2589 highlightAllUnder: function(container, async, callback) { 2590 var env = { 2591 callback: callback, 2592 container: container, 2593 selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code' 2594 }; 2595 2596 _.hooks.run('before-highlightall', env); 2597 2598 env.elements = Array.prototype.slice.apply(env.container.querySelectorAll(env.selector)); 2599 2600 _.hooks.run('before-all-elements-highlight', env); 2601 2602 for (var i = 0, element; element = env.elements[i++];) { 2603 _.highlightElement(element, async === true, env.callback); 2604 } 2605 }, 2606 2607 highlightElement: function(element, async, callback) { 2608 // Find language 2609 var language = _.util.getLanguage(element); 2610 var grammar = _.languages[language]; 2611 2612 // Set language on the element, if not present 2613 element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; 2614 2615 // Set language on the parent, for styling 2616 var parent = element.parentNode; 2617 if (parent && parent.nodeName.toLowerCase() === 'pre') { 2618 parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; 2619 } 2620 2621 var code = element.textContent; 2622 2623 var env = { 2624 element: element, 2625 language: language, 2626 grammar: grammar, 2627 code: code 2628 }; 2629 2630 function insertHighlightedCode(highlightedCode) { 2631 env.highlightedCode = highlightedCode; 2632 2633 _.hooks.run('before-insert', env); 2634 2635 env.element.innerHTML = env.highlightedCode; 2636 2637 _.hooks.run('after-highlight', env); 2638 _.hooks.run('complete', env); 2639 callback && callback.call(env.element); 2640 } 2641 2642 _.hooks.run('before-sanity-check', env); 2643 2644 if (!env.code) { 2645 _.hooks.run('complete', env); 2646 callback && callback.call(env.element); 2647 return; 2648 } 2649 2650 _.hooks.run('before-highlight', env); 2651 2652 if (!env.grammar) { 2653 insertHighlightedCode(_.util.encode(env.code)); 2654 return; 2655 } 2656 2657 if (async && _self.Worker) { 2658 var worker = new Worker(_.filename); 2659 2660 worker.onmessage = function(evt) { 2661 insertHighlightedCode(evt.data); 2662 }; 2663 2664 worker.postMessage(JSON.stringify({ 2665 language: env.language, 2666 code: env.code, 2667 immediateClose: true 2668 })); 2669 } 2670 else { 2671 insertHighlightedCode(_.highlight(env.code, env.grammar, env.language)); 2672 } 2673 }, 2674 2675 highlight: function (text, grammar, language) { 2676 var env = { 2677 code: text, 2678 grammar: grammar, 2679 language: language 2680 }; 2681 _.hooks.run('before-tokenize', env); 2682 env.tokens = _.tokenize(env.code, env.grammar); 2683 _.hooks.run('after-tokenize', env); 2684 return Token.stringify(_.util.encode(env.tokens), env.language); 2685 }, 2686 2687 tokenize: function(text, grammar) { 2688 var rest = grammar.rest; 2689 if (rest) { 2690 for (var token in rest) { 2691 grammar[token] = rest[token]; 2692 } 2693 2694 delete grammar.rest; 2695 } 2696 2697 var tokenList = new LinkedList(); 2698 addAfter(tokenList, tokenList.head, text); 2699 2700 matchGrammar(text, tokenList, grammar, tokenList.head, 0); 2701 2702 return toArray(tokenList); 2703 }, 2704 2705 hooks: { 2706 all: {}, 2707 2708 add: function (name, callback) { 2709 var hooks = _.hooks.all; 2710 2711 hooks[name] = hooks[name] || []; 2712 2713 hooks[name].push(callback); 2714 }, 2715 2716 run: function (name, env) { 2717 var callbacks = _.hooks.all[name]; 2718 2719 if (!callbacks || !callbacks.length) { 2720 return; 2721 } 2722 2723 for (var i=0, callback; callback = callbacks[i++];) { 2724 callback(env); 2725 } 2726 } 2727 }, 2728 2729 Token: Token 2730 }; 2731 2732 _self.Prism = _; 2733 2734 function Token(type, content, alias, matchedStr, greedy) { 2735 this.type = type; 2736 this.content = content; 2737 this.alias = alias; 2738 // Copy of the full string this token was created from 2739 this.length = (matchedStr || '').length|0; 2740 this.greedy = !!greedy; 2741 } 2742 2743 Token.stringify = function stringify(o, language) { 2744 if (typeof o == 'string') { 2745 return o; 2746 } 2747 if (Array.isArray(o)) { 2748 var s = ''; 2749 o.forEach(function (e) { 2750 s += stringify(e, language); 2751 }); 2752 return s; 2753 } 2754 2755 var env = { 2756 type: o.type, 2757 content: stringify(o.content, language), 2758 tag: 'span', 2759 classes: ['token', o.type], 2760 attributes: {}, 2761 language: language 2762 }; 2763 2764 var aliases = o.alias; 2765 if (aliases) { 2766 if (Array.isArray(aliases)) {
2767 Array.prototype.push.apply(env.classes, aliases); 2768 } else { 2769 env.classes.push(aliases); 2770 } 2771 } 2772 2773 _.hooks.run('wrap', env); 2774 2775 var attributes = ''; 2776 for (var name in env.attributes) { 2777 attributes += ' ' + name + '="' + (env.attributes[name] || '').replace(/"/g, '"') + '"'; 2778 } 2779 2780 return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + attributes + '>' + env.content + '</' + env.tag + '>'; 2781 }; 2782 2783 /** 2784 * @param {string} text 2785 * @param {LinkedList<string | Token>} tokenList 2786 * @param {any} grammar 2787 * @param {LinkedListNode<string | Token>} startNode 2788 * @param {number} startPos 2789 * @param {boolean} [oneshot=false] 2790 * @param {string} [target] 2791 */ 2792 function matchGrammar(text, tokenList, grammar, startNode, startPos, oneshot, target) { 2793 for (var token in grammar) { 2794 if (!grammar.hasOwnProperty(token) || !grammar[token]) { 2795 continue; 2796 } 2797 2798 var patterns = grammar[token]; 2799 patterns = Array.isArray(patterns) ? patterns : [patterns]; 2800 2801 for (var j = 0; j < patterns.length; ++j) { 2802 if (target && target == token + ',' + j) { 2803 return; 2804 } 2805 2806 var pattern = patterns[j], 2807 inside = pattern.inside, 2808 lookbehind = !!pattern.lookbehind, 2809 greedy = !!pattern.greedy, 2810 lookbehindLength = 0, 2811 alias = pattern.alias; 2812 2813 if (greedy && !pattern.pattern.global) { 2814 // Without the global flag, lastIndex won't work 2815 var flags = pattern.pattern.toString().match(/[imsuy]*$/)[0]; 2816 pattern.pattern = RegExp(pattern.pattern.source, flags + 'g'); 2817 } 2818 2819 pattern = pattern.pattern || pattern; 2820 2821 for ( // iterate the token list and keep track of the current token/string position 2822 var currentNode = startNode.next, pos = startPos; 2823 currentNode !== tokenList.tail; 2824 pos += currentNode.value.length, currentNode = currentNode.next 2825 ) { 2826 2827 var str = currentNode.value; 2828 2829 if (tokenList.length > text.length) { 2830 // Something went terribly wrong, ABORT, ABORT! 2831 return; 2832 } 2833 2834 if (str instanceof Token) { 2835 continue; 2836 } 2837 2838 var removeCount = 1; // this is the to parameter of removeBetween 2839 2840 if (greedy && currentNode != tokenList.tail.prev) { 2841 pattern.lastIndex = pos; 2842 var match = pattern.exec(text); 2843 if (!match) { 2844 break; 2845 } 2846 2847 var from = match.index + (lookbehind && match[1] ? match[1].length : 0); 2848 var to = match.index + match[0].length; 2849 var p = pos; 2850 2851 // find the node that contains the match 2852 p += currentNode.value.length; 2853 while (from >= p) { 2854 currentNode = currentNode.next; 2855 p += currentNode.value.length; 2856 } 2857 // adjust pos (and p) 2858 p -= currentNode.value.length; 2859 pos = p; 2860 2861 // the current node is a Token, then the match starts inside another Token, which is invalid 2862 if (currentNode.value instanceof Token) { 2863 continue; 2864 } 2865 2866 // find the last node which is affected by this match 2867 for ( 2868 var k = currentNode; 2869 k !== tokenList.tail && (p < to || (typeof k.value === 'string' && !k.prev.value.greedy)); 2870 k = k.next 2871 ) { 2872 removeCount++; 2873 p += k.value.length; 2874 } 2875 removeCount--; 2876 2877 // replace with the new match 2878 str = text.slice(pos, p); 2879 match.index -= pos; 2880 } else { 2881 pattern.lastIndex = 0; 2882 2883 var match = pattern.exec(str); 2884 } 2885 2886 if (!match) { 2887 if (oneshot) { 2888 break; 2889 } 2890 2891 continue; 2892 } 2893 2894 if (lookbehind) { 2895 lookbehindLength = match[1] ? match[1].length : 0; 2896 } 2897 2898 var from = match.index + lookbehindLength, 2899 match = match[0].slice(lookbehindLength), 2900 to = from + match.length, 2901 before = str.slice(0, from), 2902 after = str.slice(to); 2903 2904 var removeFrom = currentNode.prev; 2905 2906 if (before) { 2907 removeFrom = addAfter(tokenList, removeFrom, before); 2908 pos += before.length; 2909 } 2910 2911 removeRange(tokenList, removeFrom, removeCount); 2912 2913 var wrapped = new Token(token, inside ? _.tokenize(match, inside) : match, alias, match, greedy); 2914 currentNode = addAfter(tokenList, removeFrom, wrapped); 2915 2916 if (after) { 2917 addAfter(tokenList, currentNode, after); 2918 } 2919 2920
2921 if (removeCount > 1) 2922 matchGrammar(text, tokenList, grammar, currentNode.prev, pos, true, token + ',' + j); 2923 2924 if (oneshot) 2925 break; 2926 } 2927 } 2928 } 2929 } 2930 2931 /** 2932 * @typedef LinkedListNode 2933 * @property {T} value 2934 * @property {LinkedListNode<T> | null} prev The previous node. 2935 * @property {LinkedListNode<T> | null} next The next node. 2936 * @template T 2937 */ 2938 2939 /** 2940 * @template T 2941 */ 2942 function LinkedList() { 2943 /** @type {LinkedListNode<T>} */ 2944 var head = { value: null, prev: null, next: null }; 2945 /** @type {LinkedListNode<T>} */ 2946 var tail = { value: null, prev: head, next: null }; 2947 head.next = tail; 2948 2949 /** @type {LinkedListNode<T>} */ 2950 this.head = head; 2951 /** @type {LinkedListNode<T>} */ 2952 this.tail = tail; 2953 this.length = 0; 2954 } 2955 2956 /** 2957 * Adds a new node with the given value to the list. 2958 * @param {LinkedList<T>} list 2959 * @param {LinkedListNode<T>} node 2960 * @param {T} value 2961 * @returns {LinkedListNode<T>} The added node. 2962 * @template T 2963 */ 2964 function addAfter(list, node, value) { 2965 // assumes that node != list.tail && values.length >= 0 2966 var next = node.next; 2967 2968 var newNode = { value: value, prev: node, next: next }; 2969 node.next = newNode; 2970 next.prev = newNode; 2971 list.length++; 2972 2973 return newNode; 2974 } 2975 /** 2976 * Removes `count` nodes after the given node. The given node will not be removed. 2977 * @param {LinkedList<T>} list 2978 * @param {LinkedListNode<T>} node 2979 * @param {number} count 2980 * @template T 2981 */ 2982 function removeRange(list, node, count) { 2983 var next = node.next; 2984 for (var i = 0; i < count && next !== list.tail; i++) { 2985 next = next.next; 2986 } 2987 node.next = next; 2988 next.prev = node; 2989 list.length -= i; 2990 } 2991 /** 2992 * @param {LinkedList<T>} list 2993 * @returns {T[]} 2994 * @template T 2995 */ 2996 function toArray(list) { 2997 var array = []; 2998 var node = list.head.next; 2999 while (node !== list.tail) { 3000 array.push(node.value); 3001 node = node.next; 3002 } 3003 return array; 3004 } 3005 3006 3007 if (!_self.document) { 3008 if (!_self.addEventListener) { 3009 // in Node.js 3010 return _; 3011 } 3012 3013 if (!_.disableWorkerMessageHandler) { 3014 // In worker 3015 _self.addEventListener('message', function (evt) { 3016 var message = JSON.parse(evt.data), 3017 lang = message.language, 3018 code = message.code, 3019 immediateClose = message.immediateClose; 3020 3021 _self.postMessage(_.highlight(code, _.languages[lang], lang)); 3022 if (immediateClose) { 3023 _self.close(); 3024 } 3025 }, false); 3026 } 3027 3028 return _; 3029 } 3030 3031 //Get current script and highlight 3032 var script = _.util.currentScript(); 3033 3034 if (script) { 3035 _.filename = script.src; 3036 3037 if (script.hasAttribute('data-manual')) { 3038 _.manual = true; 3039 } 3040 } 3041 3042 function highlightAutomaticallyCallback() { 3043 if (!_.manual) { 3044 _.highlightAll(); 3045 } 3046 } 3047 3048 if (!_.manual) { 3049 // If the document state is "loading", then we'll use DOMContentLoaded. 3050 // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the 3051 // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they 3052 // might take longer one animation frame to execute which can create a race condition where only some plugins have 3053 // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded. 3054 // See https://github.com/PrismJS/prism/issues/2102 3055 var readyState = document.readyState; 3056 if (readyState === 'loading' || readyState === 'interactive' && script && script.defer) { 3057 document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback); 3058 } else { 3059 if (window.requestAnimationFrame) { 3060 window.requestAnimationFrame(highlightAutomaticallyCallback); 3061 } else { 3062 window.setTimeout(highlightAutomaticallyCallback, 16); 3063 } 3064 } 3065 } 3066 3067 return _; 3068 3069 })(_self); 3070 3071 if ( module.exports) { 3072 module.exports = Prism; 3073 } 3074 3075 // hack for components to work correctly in node.js 3076 if (typeof commonjsGlobal !== 'undefined') { 3077 commonjsGlobal.Prism = Prism; 3078 } 3079 3080 3081 /* ********************************************** 3082 Begin prism-markup.js 3083 ********************************************** */ 3084 3085 Prism.languages.markup = { 3086 'comment': /<!--[\s\S]*?-->/, 3087 'prolog': /<\?[\s\S]+?\?>/, 3088 'doctype': { 3089 pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:(?!<!--)[^"'\]]|"[^"]*"|'[^']*'|<!--[\s\S]*?-->)*\]\s*)?>/i, 3090 greedy: true 3091 }, 3092 'cdata': /<!\[CDATA\[[\s\S]*?]]>/i, 3093 'tag': { 3094 pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>
3094\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/i, 3095 greedy: true, 3096 inside: { 3097 'tag': { 3098 pattern: /^<\/?[^\s>\/]+/i, 3099 inside: { 3100 'punctuation': /^<\/?/, 3101 'namespace': /^[^\s>\/:]+:/ 3102 } 3103 }, 3104 'attr-value': { 3105 pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/i, 3106 inside: { 3107 'punctuation': [ 3108 /^=/, 3109 { 3110 pattern: /^(\s*)["']|["']$/, 3111 lookbehind: true 3112 } 3113 ] 3114 } 3115 }, 3116 'punctuation': /\/?>/, 3117 'attr-name': { 3118 pattern: /[^\s>\/]+/, 3119 inside: { 3120 'namespace': /^[^\s>\/:]+:/ 3121 } 3122 } 3123 3124 } 3125 }, 3126 'entity': /&#?[\da-z]{1,8};/i 3127 }; 3128 3129 Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] = 3130 Prism.languages.markup['entity']; 3131 3132 // Plugin to make entity title show the real entity, idea by Roman Komarov 3133 Prism.hooks.add('wrap', function(env) { 3134 3135 if (env.type === 'entity') { 3136 env.attributes['title'] = env.content.replace(/&/, '&'); 3137 } 3138 }); 3139 3140 Object.defineProperty(Prism.languages.markup.tag, 'addInlined', { 3141 /** 3142 * Adds an inlined language to markup. 3143 * 3144 * An example of an inlined language is CSS with `<style>` tags. 3145 * 3146 * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as 3147 * case insensitive. 3148 * @param {string} lang The language key. 3149 * @example 3150 * addInlined('style', 'css'); 3151 */ 3152 value: function addInlined(tagName, lang) { 3153 var includedCdataInside = {}; 3154 includedCdataInside['language-' + lang] = { 3155 pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i, 3156 lookbehind: true, 3157 inside: Prism.languages[lang] 3158 }; 3159 includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i; 3160 3161 var inside = { 3162 'included-cdata': { 3163 pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i, 3164 inside: includedCdataInside 3165 } 3166 }; 3167 inside['language-' + lang] = { 3168 pattern: /[\s\S]+/, 3169 inside: Prism.languages[lang] 3170 }; 3171 3172 var def = {}; 3173 def[tagName] = { 3174 pattern: RegExp(/(<__[\s\S]*?>)(?:<!\[CDATA\[[\s\S]*?\]\]>\s*|[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { return tagName; }), 'i'), 3175 lookbehind: true, 3176 greedy: true, 3177 inside: inside 3178 }; 3179 3180 Prism.languages.insertBefore('markup', 'cdata', def); 3181 } 3182 }); 3183 3184 Prism.languages.xml = Prism.languages.extend('markup', {}); 3185 Prism.languages.html = Prism.languages.markup; 3186 Prism.languages.mathml = Prism.languages.markup; 3187 Prism.languages.svg = Prism.languages.markup; 3188 3189 3190 /* ********************************************** 3191 Begin prism-css.js 3192 ********************************************** */ 3193 3194 (function (Prism) { 3195 3196 var string = /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/; 3197 3198 Prism.languages.css = { 3199 'comment': /\/\*[\s\S]*?\*\//, 3200 'atrule': { 3201 pattern: /@[\w-]+[\s\S]*?(?:;|(?=\s*\{))/, 3202 inside: { 3203 'rule': /^@[\w-]+/, 3204 'selector-function-argument': { 3205 pattern: /(\bselector\s*\((?!\s*\))\s*)(?:[^()]|\((?:[^()]|\([^()]*\))*\))+?(?=\s*\))/, 3206 lookbehind: true, 3207 alias: 'selector' 3208 } 3209 // See rest below 3210 } 3211 }, 3212 'url': { 3213 pattern: RegExp('url\\((?:' + string.source + '|[^\n\r()]*)\\)', 'i'), 3214 greedy: true, 3215 inside: { 3216 'function': /^url/i, 3217 'punctuation': /^\(|\)$/ 3218 } 3219 }, 3220 'selector': RegExp('[^{}\\s](?:[^{};"\']|' + string.source + ')*?(?=\\s*\\{)'), 3221 'string': { 3222 pattern: string, 3223 greedy: true 3224 }, 3225 'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i, 3226 'important': /!important\b/i, 3227 'function': /[-a-z0-9]+(?=\()/i, 3228 'punctuation': /[(){};:,]/ 3229 }; 3230 3231 Prism.languages.css['atrule'].inside.rest = Prism.languages.css; 3232 3233 var markup = Prism.languages.markup; 3234 if (markup) { 3235 markup.tag.addInlined('style', 'css'); 3236 3237 Prism.languages.insertBefore('inside', 'attr-value', { 3238 'style-attr': { 3239 pattern: /\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i, 3240 inside: { 3241 'attr-name': { 3242 pattern: /^\s*style/i, 3243 inside: markup.tag.inside 3244 }, 3245 'punctuation': /^\s*=\s*['"]|['"]\s*$/, 3246 'attr-value': { 3247 pattern: /.+/i, 3248 inside: Prism.languages.css 3249 } 3250 }, 3251 alias: 'language-css' 3252 } 3253 }, markup.tag); 3254 } 3255 3256 }(Prism)); 3257 3258 3259 /* ********************************************** 3260 Begin prism-clike.js 3261 ********************************************** */ 3262 3263 Prism.languages.clike = { 3264 'comment': [ 3265 { 3266 pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/, 3267 lookbehind: true 3268 }, 3269 { 3270 pattern: /(^|[^\\:])\/\/.*/, 3271 lookbehind: true, 3272 greedy: true 3273 } 3274 ], 3275 'string': { 3276 pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, 3277 greedy: true 3278 }, 3279 'class-name': { 3280 pattern: /(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i, 3281 lookbehind: true, 3282 inside: { 3283 'punctuation': /[.\\]/ 3284 } 3285 }, 3286 'keyword': /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/, 3287 'boolean': /\b(?:true|false)\b/, 3288 'function': /\w+(?=\()/, 3289 'number': /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i, 3290 'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/, 3291 'punctuation': /[{}[\];(),.:]/ 3292 }; 3293 3294 3295 /* ********************************************** 3296 Begin prism-javascript.js 3297 ********************************************** */ 3298 3299 Prism.languages.javascript = Prism.languages.extend('clike', { 3300 'class-name': [ 3301 Prism.languages.clike['class-name'], 3302 { 3303 pattern: /(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/, 3304 lookbehind: true 3305 } 3306 ], 3307 'keyword': [ 3308 { 3309 pattern: /((?:^|})\s*)(?:catch|finally)\b/, 3310 lookbehind: true 3311 }, 3312 { 3313 pattern: /(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/, 3314 lookbehind: true 3315 }, 3316 ], 3317 'number': /\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/, 3318 // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444) 3319 'function': /#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/, 3320 'operator': /--|\+\+|\*\*=?|=>|&&|\|\||[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?[.?]?|[~:]/ 3321 }); 3322 3323 Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/; 3324 3325 Prism.languages.insertBefore('javascript', 'keyword', { 3326 'regex': { 3327 pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*[\s\S]*?\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/, 3328 lookbehind: true, 3329 greedy: true 3330 }, 3331 // This must be declared before keyword because we use "function" inside the look-forward 3332 'function-variable': { 3333 pattern: /#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]
3333*\))*\)|[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/, 3334 alias: 'function' 3335 }, 3336 'parameter': [ 3337 { 3338 pattern: /(function(?:\s+[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)?\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\))/, 3339 lookbehind: true, 3340 inside: Prism.languages.javascript 3341 }, 3342 { 3343 pattern: /[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=>)/i, 3344 inside: Prism.languages.javascript 3345 }, 3346 { 3347 pattern: /(\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*=>)/, 3348 lookbehind: true, 3349 inside: Prism.languages.javascript 3350 }, 3351 { 3352 pattern: /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*)\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*\{)/, 3353 lookbehind: true, 3354 inside: Prism.languages.javascript 3355 } 3356 ], 3357 'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/ 3358 }); 3359 3360 Prism.languages.insertBefore('javascript', 'string', { 3361 'template-string': { 3362 pattern: /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/, 3363 greedy: true, 3364 inside: { 3365 'template-punctuation': { 3366 pattern: /^`|`$/, 3367 alias: 'string' 3368 }, 3369 'interpolation': { 3370 pattern: /((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/, 3371 lookbehind: true, 3372 inside: { 3373 'interpolation-punctuation': { 3374 pattern: /^\${|}$/, 3375 alias: 'punctuation' 3376 }, 3377 rest: Prism.languages.javascript 3378 } 3379 }, 3380 'string': /[\s\S]+/ 3381 } 3382 } 3383 }); 3384 3385 if (Prism.languages.markup) { 3386 Prism.languages.markup.tag.addInlined('script', 'javascript'); 3387 } 3388 3389 Prism.languages.js = Prism.languages.javascript; 3390 3391 3392 /* ********************************************** 3393 Begin prism-file-highlight.js 3394 ********************************************** */ 3395 3396 (function () { 3397 if (typeof self === 'undefined' || !self.Prism || !self.document || !document.querySelector) { 3398 return; 3399 } 3400 3401 /** 3402 * @param {Element} [container=document] 3403 */ 3404 self.Prism.fileHighlight = function(container) { 3405 container = container || document; 3406 3407 var Extensions = { 3408 'js': 'javascript', 3409 'py': 'python', 3410 'rb': 'ruby', 3411 'ps1': 'powershell', 3412 'psm1': 'powershell', 3413 'sh': 'bash', 3414 'bat': 'batch', 3415 'h': 'c', 3416 'tex': 'latex' 3417 }; 3418 3419 Array.prototype.slice.call(container.querySelectorAll('pre[data-src]')).forEach(function (pre) { 3420 // ignore if already loaded 3421 if (pre.hasAttribute('data-src-loaded')) { 3422 return; 3423 } 3424 3425 // load current 3426 var src = pre.getAttribute('data-src'); 3427 3428 var language, parent = pre; 3429 var lang = /\blang(?:uage)?-([\w-]+)\b/i; 3430 while (parent && !lang.test(parent.className)) { 3431 parent = parent.parentNode; 3432 } 3433 3434 if (parent) { 3435 language = (pre.className.match(lang) || [, ''])[1]; 3436 } 3437 3438 if (!language) { 3439 var extension = (src.match(/\.(\w+)$/) || [, ''])[1]; 3440 language = Extensions[extension] || extension; 3441 } 3442 3443 var code = document.createElement('code'); 3444 code.className = 'language-' + language; 3445 3446 pre.textContent = ''; 3447 3448 code.textContent = 'Loadingâ¦'; 3449 3450 pre.appendChild(code); 3451 3452 var xhr = new XMLHttpRequest(); 3453 3454 xhr.open('GET', src, true); 3455 3456 xhr.onreadystatechange = function () { 3457 if (xhr.readyState == 4) { 3458 3459 if (xhr.status < 400 && xhr.responseText) { 3460 code.textContent = xhr.responseText; 3461 3462 Prism.highlightElement(code); 3463 // mark as loaded 3464 pre.setAttribute('data-src-loaded', ''); 3465 } 3466 else if (xhr.status >= 400) { 3467 code.textContent = 'â Error ' + xhr.status + ' while fetching file: ' + xhr.statusText; 3468 } 3469 else { 3470 code.textContent = 'â Error: File does not exist or is empty'; 3471 } 3472 } 3473 }; 3474 3475 xhr.send(null); 3476 }); 3477 }; 3478 3479 document.addEventListener('DOMContentLoaded', function () { 3480 // execute inside handler, for dropping Event as argument 3481 self.Prism.fileHighlight(); 3482 }); 3483 3484 })(); 3485 }); 3486 3487 Prism.languages.python = { 3488 'comment': { 3489 pattern: /(^|[^\\])#.*/, 3490 lookbehind: true 3491 }, 3492 'string-interpolation': { 3493 pattern: /(?:f|rf|fr)(?:("""|''')[\s\S]+?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i, 3494 greedy: true, 3495 inside: { 3496 'interpolation': { 3497 // "{" <expression> <optional "!s", "!r", or "!a"> <optional ":" format specifier> "}" 3498 pattern: /((?:^|[^{])(?:{{)*){(?!{)(?:[^{}]|{(?!{)(?:[^{}]|{(?!{)(?:[^{}])+})+})+}/, 3499 lookbehind: true, 3500 inside: { 3501 'format-spec': { 3502 pattern: /(:)[^:(){}]+(?=}$)/, 3503 lookbehind: true 3504 }, 3505 'conversion-option': { 3506 pattern: //, 3507 alias: 'punctuation' 3508 }, 3509 rest: null 3510 } 3511 }, 3512 'string': /[\s\S]+/ 3513 } 3514 }, 3515 'triple-quoted-string': { 3516 pattern: /(?:[rub]|rb|br)?("""|''')[\s\S]+?\1/i, 3517 greedy: true, 3518 alias: 'string' 3519 }, 3520 'string': { 3521 pattern: /(?:[rub]|rb|br)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i, 3522 greedy: true 3523 }, 3524 'function': { 3525 pattern: /((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g, 3526 lookbehind: true 3527 }, 3528 'class-name': { 3529 pattern: /(\bclass\s+)\w+/i, 3530 lookbehind: true 3531 }, 3532 'decorator': { 3533 pattern: /(^\s*)@\w+(?:\.\w+)*/im, 3534 lookbehind: true, 3535 alias: ['annotation', 'punctuation'], 3536 inside: { 3537 'punctuation': /\./ 3538 } 3539 }, 3540 'keyword': /\b(?:and|as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/, 3541 'builtin': /\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/, 3542 'boolean': /\b(?:True|False|None)\b/, 3543 'number': /(?:\b(?=\d)|\B(?=\.))(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i, 3544 'operator': /[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/, 3545 'punctuation': /[{}[\];(),.:]/ 3546 }; 3547
3548 Prism.languages.python['string-interpolation'].inside['interpolation'].inside.rest = Prism.languages.python; 3549 3550 Prism.languages.py = Prism.languages.python; 3551 3552 Prism.languages.clike = { 3553 'comment': [ 3554 { 3555 pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/, 3556 lookbehind: true 3557 }, 3558 { 3559 pattern: /(^|[^\\:])\/\/.*/, 3560 lookbehind: true, 3561 greedy: true 3562 } 3563 ], 3564 'string': { 3565 pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, 3566 greedy: true 3567 }, 3568 'class-name': { 3569 pattern: /(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i, 3570 lookbehind: true, 3571 inside: { 3572 'punctuation': /[.\\]/ 3573 } 3574 }, 3575 'keyword': /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/, 3576 'boolean': /\b(?:true|false)\b/, 3577 'function': /\w+(?=\()/, 3578 'number': /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i, 3579 'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/, 3580 'punctuation': /[{}[\];(),.:]/ 3581 }; 3582 3583 Prism.languages.lua = { 3584 'comment': /^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m, 3585 // \z may be used to skip the following space 3586 'string': { 3587 pattern: /(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[\s\S]))*\1|\[(=*)\[[\s\S]*?\]\2\]/, 3588 greedy: true 3589 }, 3590 'number': /\b0x[a-f\d]+\.?[a-f\d]*(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|\.?\d*(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i, 3591 'keyword': /\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/, 3592 'function': /(?!\d)\w+(?=\s*(?:[({]))/, 3593 'operator': [ 3594 /[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/, 3595 { 3596 // Match ".." but don't break "..." 3597 pattern: /(^|[^.])\.\.(?!\.)/, 3598 lookbehind: true 3599 } 3600 ], 3601 'punctuation': /[\[\](){},;]|\.+|:+/ 3602 }; 3603 3604 (function(Prism) { 3605 // $ set | grep '^[A-Z][^[:space:]]*=' | cut -d= -f1 | tr '\n' '|' 3606 // + LC_ALL, RANDOM, REPLY, SECONDS. 3607 // + make sure PS1..4 are here as they are not always set, 3608 // - some useless things. 3609 var envVars = '\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_
3609CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b'; 3610 var insideString = { 3611 'environment': { 3612 pattern: RegExp("\\$" + envVars), 3613 alias: 'constant' 3614 }, 3615 'variable': [ 3616 // [0]: Arithmetic Environment 3617 { 3618 pattern: /\$?\(\([\s\S]+?\)\)/, 3619 greedy: true, 3620 inside: { 3621 // If there is a $ sign at the beginning highlight $(( and )) as variable 3622 'variable': [ 3623 { 3624 pattern: /(^\$\(\([\s\S]+)\)\)/, 3625 lookbehind: true 3626 }, 3627 /^\$\(\(/ 3628 ], 3629 'number': /\b0x[\dA-Fa-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee]-?\d+)?/, 3630 // Operators according to https://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic 3631 'operator': /--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/, 3632 // If there is no $ sign at the beginning highlight (( and )) as punctuation 3633 'punctuation': /\(\(?|\)\)?|,|;/ 3634 } 3635 }, 3636 // [1]: Command Substitution 3637 { 3638 pattern: /\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/, 3639 greedy: true, 3640 inside: { 3641 'variable': /^\$\(|^`|\)$|`$/ 3642 } 3643 }, 3644 // [2]: Brace expansion 3645 { 3646 pattern: /\$\{[^}]+\}/, 3647 greedy: true, 3648 inside: { 3649 'operator': /:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/, 3650 'punctuation': /[\[\]]/, 3651 'environment': { 3652 pattern: RegExp("(\\{)" + envVars), 3653 lookbehind: true, 3654 alias: 'constant' 3655 } 3656 } 3657 }, 3658 /\$(?:\w+|[#?*!@$])/ 3659 ], 3660 // Escape sequences from echo and printf's manuals, and escaped quotes. 3661 'entity': /\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|x[0-9a-fA-F]{1,2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})/ 3662 }; 3663 3664 Prism.languages.bash = { 3665 'shebang': { 3666 pattern: /^#!\s*\/.*/, 3667 alias: 'important' 3668 }, 3669 'comment': { 3670 pattern: /(^|[^"{\\$])#.*/, 3671 lookbehind: true 3672 }, 3673 'function-name': [ 3674 // a) function foo { 3675 // b) foo() { 3676 // c) function foo() { 3677 // but not âfoo {â 3678 { 3679 // a) and c) 3680 pattern: /(\bfunction\s+)\w+(?=(?:\s*\(?:\s*\))?\s*\{)/, 3681 lookbehind: true, 3682 alias: 'function' 3683 }, 3684 { 3685 // b) 3686 pattern: /\b\w+(?=\s*\(\s*\)\s*\{)/, 3687 alias: 'function' 3688 } 3689 ], 3690 // Highlight variable names as variables in for and select beginnings. 3691 'for-or-select': { 3692 pattern: /(\b(?:for|select)\s+)\w+(?=\s+in\s)/, 3693 alias: 'variable', 3694 lookbehind: true 3695 }, 3696 // Highlight variable names as variables in the left-hand part 3697 // of assignments (â=â and â+=â). 3698 'assign-left': { 3699 pattern: /(^|[\s;|&]|[<>]\()\w+(?=\+?=)/, 3700 inside: { 3701 'environment': { 3702 pattern: RegExp("(^|[\\s;|&]|[<>]\\()" + envVars), 3703 lookbehind: true, 3704 alias: 'constant' 3705 } 3706 }, 3707 alias: 'variable', 3708 lookbehind: true 3709 }, 3710 'string': [ 3711 // Support for Here-documents https://en.wikipedia.org/wiki/Here_document 3712 { 3713 pattern: /((?:^|[^<])<<-?\s*)(\w+?)\s*(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\2/, 3714 lookbehind: true, 3715 greedy: true, 3716 inside: insideString 3717 }, 3718 // Here-document with quotes around the tag 3719 // â No expansion (so no âinsideâ). 3720 { 3721 pattern: /((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s*(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\3/, 3722 lookbehind: true, 3723 greedy: true 3724 }, 3725 // âNormalâ string 3726 { 3727 pattern: /(^|[^\\](?:\\\\)*)(["'])(?:\\[\s\S]|\$\([^)]+\)|`[^`]+`|(?!\2)[^\\])*\2/, 3728 lookbehind: true, 3729 greedy: true, 3730 inside: insideString 3731 } 3732 ], 3733 'environment': { 3734 pattern: RegExp("\\$?" + envVars), 3735 alias: 'constant' 3736 }, 3737 'variable': insideString.variable, 3738 'function': { 3739 pattern: /(^|[\s;|&]|[<>]\()(?:add|apropos|apt|aptitude|apt-cache|apt-get|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|
3739ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/, 3740 lookbehind: true 3741 }, 3742 'keyword': { 3743 pattern: /(^|[\s;|&]|[<>]\()(?:if|then|else|elif|fi|for|while|in|case|esac|function|select|do|done|until)(?=$|[)\s;|&])/, 3744 lookbehind: true 3745 }, 3746 // https://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html 3747 'builtin': { 3748 pattern: /(^|[\s;|&]|[<>]\()(?:\.|:|break|cd|continue|eval|exec|exit|export|getopts|hash|pwd|readonly|return|shift|test|times|trap|umask|unset|alias|bind|builtin|caller|command|declare|echo|enable|help|let|local|logout|mapfile|printf|read|readarray|source|type|typeset|ulimit|unalias|set|shopt)(?=$|[)\s;|&])/, 3749 lookbehind: true, 3750 // Alias added to make those easier to distinguish from strings. 3751 alias: 'class-name' 3752 }, 3753 'boolean': { 3754 pattern: /(^|[\s;|&]|[<>]\()(?:true|false)(?=$|[)\s;|&])/, 3755 lookbehind: true 3756 }, 3757 'file-descriptor': { 3758 pattern: /\B&\d\b/, 3759 alias: 'important' 3760 }, 3761 'operator': { 3762 // Lots of redirections here, but not just that. 3763 pattern: /\d?<>|>\||\+=|==?|!=?|=~|<<[<-]?|[&\d]?>>|\d?[<>]&?|&[>&]?|\|[&|]?|<=?|>=?/, 3764 inside: { 3765 'file-descriptor': { 3766 pattern: /^\d/, 3767 alias: 'important' 3768 } 3769 } 3770 }, 3771 'punctuation': /\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/, 3772 'number': { 3773 pattern: /(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/, 3774 lookbehind: true 3775 } 3776 }; 3777 3778 /* Patterns in command substitution. */ 3779 var toBeCopied = [ 3780 'comment', 3781 'function-name', 3782 'for-or-select', 3783 'assign-left', 3784 'string', 3785 'environment', 3786 'function', 3787 'keyword', 3788 'builtin', 3789 'boolean', 3790 'file-descriptor', 3791 'operator', 3792 'punctuation', 3793 'number' 3794 ]; 3795 var inside = insideString.variable[1].inside; 3796 for(var i = 0; i < toBeCopied.length; i++) { 3797 inside[toBeCopied[i]] = Prism.languages.bash[toBeCopied[i]]; 3798 } 3799 3800 Prism.languages.shell = Prism.languages.bash; 3801 })(Prism); 3802 3803 Prism.languages.go = Prism.languages.extend('clike', { 3804 'keyword': /\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/, 3805 'builtin': /\b(?:bool|byte|complex(?:64|128)|error|float(?:32|64)|rune|string|u?int(?:8|16|32|64)?|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(?:ln)?|real|recover)\b/, 3806 'boolean': /\b(?:_|iota|nil|true|false)\b/, 3807 'operator': /[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./, 3808 'number': /(?:\b0x[a-f\d]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e[-+]?\d+)?)i?/i, 3809 'string': { 3810 pattern: /(["'`])(?:\\[\s\S]|(?!\1)[^\\])*\1/, 3811 greedy: true 3812 } 3813 }); 3814 delete Prism.languages.go['class-name']; 3815 3816 (function (Prism) { 3817 3818 // Allow only one line break 3819 var inner = /(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?!\n|\r\n?))/.source; 3820 3821 /** 3822 * This function is intended for the creation of the bold or italic pattern. 3823 * 3824 * This also adds a lookbehind group to the given pattern to ensure that the pattern is not backslash-escaped. 3825 * 3826 * _Note:_ Keep in mind that this adds a capturing group. 3827 * 3828 * @param {string} pattern 3829 * @param {boolean} starAlternative Whether to also add an alternative where all `_`s are replaced with `*`s. 3830 * @returns {RegExp} 3831 */ 3832 function createInline(pattern, starAlternative) { 3833 pattern = pattern.replace(/<inner>/g, function () { return inner; }); 3834 if (starAlternative) { 3835 pattern = pattern + '|' + pattern.replace(/_/g, '\\*'); 3836 } 3837 return RegExp(/((?:^|[^\\])(?:\\{2}
3837)*)/.source + '(?:' + pattern + ')'); 3838 } 3839 3840 3841 var tableCell = /(?:\\.|``.+?``|`[^`\r\n]+`|[^\\|\r\n`])+/.source; 3842 var tableRow = /\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|$)/.source.replace(/__/g, function () { return tableCell; }); 3843 var tableLine = /\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source; 3844 3845 3846 Prism.languages.markdown = Prism.languages.extend('markup', {}); 3847 Prism.languages.insertBefore('markdown', 'prolog', { 3848 'blockquote': { 3849 // > ... 3850 pattern: /^>(?:[\t ]*>)*/m, 3851 alias: 'punctuation' 3852 }, 3853 'table': { 3854 pattern: RegExp('^' + tableRow + tableLine + '(?:' + tableRow + ')*', 'm'), 3855 inside: { 3856 'table-data-rows': { 3857 pattern: RegExp('^(' + tableRow + tableLine + ')(?:' + tableRow + ')*$'), 3858 lookbehind: true, 3859 inside: { 3860 'table-data': { 3861 pattern: RegExp(tableCell), 3862 inside: Prism.languages.markdown 3863 }, 3864 'punctuation': /\|/ 3865 } 3866 }, 3867 'table-line': { 3868 pattern: RegExp('^(' + tableRow + ')' + tableLine + '$'), 3869 lookbehind: true, 3870 inside: { 3871 'punctuation': /\||:?-{3,}:?/ 3872 } 3873 }, 3874 'table-header-row': { 3875 pattern: RegExp('^' + tableRow + '$'), 3876 inside: { 3877 'table-header': { 3878 pattern: RegExp(tableCell), 3879 alias: 'important', 3880 inside: Prism.languages.markdown 3881 }, 3882 'punctuation': /\|/ 3883 } 3884 } 3885 } 3886 }, 3887 'code': [ 3888 { 3889 // Prefixed by 4 spaces or 1 tab and preceded by an empty line 3890 pattern: /((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/, 3891 lookbehind: true, 3892 alias: 'keyword' 3893 }, 3894 { 3895 // `code` 3896 // ``code`` 3897 pattern: /``.+?``|`[^`\r\n]+`/, 3898 alias: 'keyword' 3899 }, 3900 { 3901 // ```optional language 3902 // code block 3903 // ``` 3904 pattern: /^```[\s\S]*?^```$/m, 3905 greedy: true, 3906 inside: { 3907 'code-block': { 3908 pattern: /^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m, 3909 lookbehind: true 3910 }, 3911 'code-language': { 3912 pattern: /^(```).+/, 3913 lookbehind: true 3914 }, 3915 'punctuation': /```/ 3916 } 3917 } 3918 ], 3919 'title': [ 3920 { 3921 // title 1 3922 // ======= 3923 3924 // title 2 3925 // ------- 3926 pattern: /\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m, 3927 alias: 'important', 3928 inside: { 3929 punctuation: /==+$|--+$/ 3930 } 3931 }, 3932 { 3933 // # title 1 3934 // ###### title 6 3935 pattern: /(^\s*)#+.+/m, 3936 lookbehind: true, 3937 alias: 'important', 3938 inside: { 3939 punctuation: /^#+|#+$/ 3940 } 3941 } 3942 ], 3943 'hr': { 3944 // *** 3945 // --- 3946 // * * * 3947 // ----------- 3948 pattern: /(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m, 3949 lookbehind: true, 3950 alias: 'punctuation' 3951 }, 3952 'list': { 3953 // * item 3954 // + item 3955 // - item 3956 // 1. item 3957 pattern: /(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m, 3958 lookbehind: true, 3959 alias: 'punctuation' 3960 }, 3961 'url-reference': { 3962 // [id]: http://example.com "Optional title" 3963 // [id]: http://example.com 'Optional title' 3964 // [id]: http://example.com (Optional title) 3965 // [id]: <http://example.com> "Optional title" 3966 pattern: /!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/, 3967 inside: { 3968 'variable': { 3969 pattern: /^(!?\[)[^\]]+/, 3970 lookbehind: true 3971 }, 3972 'string': /(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/, 3973 'punctuation': /^[\[\]!:]|[<>]/ 3974 }, 3975 alias: 'url' 3976 }, 3977 'bold': { 3978 // **strong** 3979 // __strong__ 3980 3981 // allow one nested instance of italic text using the same delimiter 3982 pattern: createInline(/__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__/.source, true), 3983 lookbehind: true, 3984 greedy: true, 3985 inside: { 3986 'content': { 3987 pattern: /(^..)[\s\S]+(?=..$)/, 3988 lookbehind: true, 3989 inside: {} // see below 3990 }, 3991 'punctuation': /\*\*|__/ 3992 } 3993 }, 3994 'italic': { 3995 // *em* 3996 // _em_ 3997 3998 // allow one nested instance of bold text using the same delimiter 3999 pattern: createInline(/_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_/.source, true), 4000 lookbehind: true, 4001 greedy: true, 4002 inside: { 4003 'content': { 4004 pattern: /(^.)[\s\S]+(?=.$)/, 4005 lookbehind: true, 4006 inside: {} // see below 4007 }, 4008 'punctuation': /[*_]/ 4009 } 4010 }, 4011 'strike': { 4012 // ~~strike through~~ 4013 // ~strike~ 4014 pattern: createInline(/(~~?)(?:(?!~)<inner>)+?\2/.source, false), 4015 lookbehind: true, 4016 greedy: true, 4017 inside: { 4018 'content': { 4019 pattern: /(^~~?)[\s\S]+(?=\1$)/, 4020 lookbehind: true, 4021 inside: {} // see below 4022 }, 4023 'punctuation': /~~?/ 4024 } 4025 }, 4026 'url': { 4027 // [example](http://example.com "Optional title") 4028 // [example][id] 4029 // [example] [id] 4030 pattern: createInline(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)| ?\[(?:(?!\])<inner>)+\])/.source, false), 4031 lookbehind: true, 4032 greedy: true, 4033 inside: { 4034 'variable': { 4035 pattern: /(\[)[^\]]+(?=\]$)/, 4036 lookbehind: true 4037 }, 4038 'content': { 4039 pattern: /(^!?\[)[^\]]+(?=\])/, 4040 lookbehind: true, 4041 inside: {} // see below 4042 }, 4043 'string': { 4044 pattern: /"(?:\\.|[^"\\])*"(?=\)$)/ 4045 } 4046 } 4047 } 4048 }); 4049 4050 ['url', 'bold', 'italic', 'strike'].forEach(function (token) { 4051 ['url', 'bold', 'italic', 'strike'].forEach(function (inside) { 4052 if (token !== inside) { 4053 Prism.languages.markdown[token].inside.content.inside[inside] = Prism.languages.markdown[inside]; 4054 } 4055 }); 4056 }); 4057 4058 Prism.hooks.add('after-tokenize', function (env) { 4059 if (env.language !== 'markdown' && env.language !== 'md') { 4060 return; 4061 } 4062 4063 function walkTokens(tokens) { 4064 if (!tokens || typeof tokens === 'string') { 4065 return; 4066 } 4067 4068 for (var i = 0, l = tokens.length; i < l; i++) { 4069 var token = tokens[i]; 4070 4071 if (token.type !== 'code') { 4072 walkTokens(token.content); 4073 continue; 4074 } 4075 4076 /* 4077 * Add the correct `language-xxxx` class to this code block. Keep in mind that the `code-language` token 4078 * is optional. But the grammar is defined so that there is only one case we have to handle: 4079 * 4080 * token.content = [ 4081 * <span class="punctuation">```</span>, 4082 * <span class="code-language">xxxx</span>, 4083 * '\n', // exactly one new lines (\r or \n or \r\n) 4084 * <span class="code-block">...</span>, 4085 * '\n', // exactly one new lines again 4086 * <span class="punctuation">```</span> 4087 * ]; 4088 */ 4089 4090 var codeLang = token.content[1]; 4091 var codeBlock = token.content[3]; 4092 4093 if (codeLang && codeBlock && 4094 codeLang.type === 'code-language' && codeBlock.type === 'code-block' && 4095 typeof codeLang.content === 'string') { 4096 4097 // this might be a language that Prism does not support 4098
4099 // do some replacements to support C++, C#, and F# 4100 var lang = codeLang.content.replace(/\b#/g, 'sharp').replace(/\b\+\+/g, 'pp'); 4101 // only use the first word 4102 lang = (/[a-z][\w-]*/i.exec(lang) || [''])[0].toLowerCase(); 4103 var alias = 'language-' + lang; 4104 4105 // add alias 4106 if (!codeBlock.alias) { 4107 codeBlock.alias = [alias]; 4108 } else if (typeof codeBlock.alias === 'string') { 4109 codeBlock.alias = [codeBlock.alias, alias]; 4110 } else { 4111 codeBlock.alias.push(alias); 4112 } 4113 } 4114 } 4115 } 4116 4117 walkTokens(env.tokens); 4118 }); 4119 4120 Prism.hooks.add('wrap', function (env) { 4121 if (env.type !== 'code-block') { 4122 return; 4123 } 4124 4125 var codeLang = ''; 4126 for (var i = 0, l = env.classes.length; i < l; i++) { 4127 var cls = env.classes[i]; 4128 var match = /language-(.+)/.exec(cls); 4129 if (match) { 4130 codeLang = match[1]; 4131 break; 4132 } 4133 } 4134 4135 var grammar = Prism.languages[codeLang]; 4136 4137 if (!grammar) { 4138 if (codeLang && codeLang !== 'none' && Prism.plugins.autoloader) { 4139 var id = 'md-' + new Date().valueOf() + '-' + Math.floor(Math.random() * 1e16); 4140 env.attributes['id'] = id; 4141 4142 Prism.plugins.autoloader.loadLanguages(codeLang, function () { 4143 var ele = document.getElementById(id); 4144 if (ele) { 4145 ele.innerHTML = Prism.highlight(ele.textContent, Prism.languages[codeLang], codeLang); 4146 } 4147 }); 4148 } 4149 } else { 4150 // reverse Prism.util.encode 4151 var code = env.content.replace(/</g, '<').replace(/&/g, '&'); 4152 4153 env.content = Prism.highlight(code, grammar, codeLang); 4154 } 4155 }); 4156 4157 Prism.languages.md = Prism.languages.markdown; 4158 4159 }(Prism)); 4160 4161 Prism.languages.julia= { 4162 'comment': { 4163 pattern: /(^|[^\\])#.*/, 4164 lookbehind: true 4165 }, 4166 'string': /("""|''')[\s\S]+?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2/, 4167 'keyword' : /\b(?:abstract|baremodule|begin|bitstype|break|catch|ccall|const|continue|do|else|elseif|end|export|finally|for|function|global|if|immutable|import|importall|in|let|local|macro|module|print|println|quote|return|struct|try|type|typealias|using|while)\b/, 4168 'boolean' : /\b(?:true|false)\b/, 4169 'number' : /(?:\b(?=\d)|\B(?=\.))(?:0[box])?(?:[\da-f]+\.?\d*|\.\d+)(?:[efp][+-]?\d+)?j?/i, 4170 'operator': /[-+*^%÷&$\\]=?|\/[\/=]?|!=?=?|\|[=>]?|<(?:<=?|[=:])?|>(?:=|>>?=?)?|==?=?|[~â â¤â¥]/, 4171 'punctuation' : /[{}[\];(),.:]/, 4172 'constant': /\b(?:(?:NaN|Inf)(?:16|32|64)?)\b/ 4173 }; 4174 4175 var css = "/**\n * prism.js default theme for JavaScript, CSS and HTML\n * Based on dabblet (http://dabblet.com)\n * @author Lea Verou\n */\n\ncode[class*=\"language-\"],\npre[class*=\"language-\"] {\n\tcolor: black;\n\tbackground: none;\n\ttext-shadow: 0 1px white;\n\tfont-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;\n\tfont-size: 1em;\n\ttext-align: left;\n\twhite-space: pre;\n\tword-spacing: normal;\n\tword-break: normal;\n\tword-wrap: normal;\n\tline-height: 1.5;\n\n\t-moz-tab-size: 4;\n\t-o-tab-size: 4;\n\ttab-size: 4;\n\n\t-webkit-hyphens: none;\n\t-moz-hyphens: none;\n\t-ms-hyphens: none;\n\thyphens: none;\n}\n\npre[class*=\"language-\"]::-moz-selection, pre[class*=\"language-\"] ::-moz-selection,\ncode[class*=\"language-\"]::-moz-selection, code[class*=\"language-\"] ::-moz-selection {\n\ttext-shadow: none;\n\tbackground: #b3d4fc;\n}\n\npre[class*=\"language-\"]::selection, pre[class*=\"language-\"] ::selection,\ncode[class*=\"language-\"]::selection, code[class*=\"language-\"] ::selection {\n\ttext-shadow: none;\n\tbackground: #b3d4fc;\n}\n\n@media print {\n\tcode[class*=\"language-\"],\n\tpre[class*=\"language-\"] {\n\t\ttext-shadow: none;\n\t}\n}\n\n/* Code blocks */\npre[class*=\"language-\"] {\n\tpadding: 1em;\n\tmargin: .5em 0;\n\toverflow: auto;\n}\n\n:not(pre) > code[class*=\"language-\"],\npre[class*=\"language-\"] {\n\tbackground: #f5f2f0;\n}\n\n/* Inline code */\n:not(pre) > code[class*=\"language-\"] {\n\tpadding: .1em;\n\tborder-radius: .3em;\n\twhite-space: normal;\n}\n\n.token.comment,\n.token.prolog,\n.token.doctype,\n.token.cdata {\n\tcolor: slategray;\n}\n\n.token.punctuation {\n\tcolor: #999;\n}\n\n.token.namespace {\n\topacity: .7;\n}\n\n.token.property,\n.token.tag,\n.token.boolean,\n.token.number,\n.token.constant,\n.token.symbol,\n.token.deleted {\n\tcolor: #905;\n}\n\n.token.selector,\n.token.attr-name,\n.token.string,\n.token.char,\n.token.builtin,\n.token.inserted {\n\tcolor: #690;\n}\n\n.token.operator,\n.token.entity,\n.token.url,\n.language-css .token.string,\n.style .token.string {\n\tcolor: #9a6e3a;\n\tbackground: hsla(0, 0%, 100%, .5);\n}\n\n.token.atrule,\n.token.attr-value,\n.token.keyword {\n\tcolor: #07a;\n}\n\n.token.function,\n.token.class-name {\n\tcolor: #DD4A68;\n}\n\n.token.regex,\n.token.important,\n.token.variable {\n\tcolor: #e90;\n}\n\n.token.important,\n.token.bold {\n\tfont-weight: bold;\n}\n.token.italic {\n\tfont-style: italic;\n}\n\n.token.entity {\n\tcursor: help;\n}\n"; 4176 4177 // Copyright 2018 The Distill Template Authors 4178 4179 const T$4 = Template('d-code', ` 4180<style> 4181 4182code { 4183 white-space: nowrap; 4184 background: rgba(0, 0, 0, 0.04); 4185 border-radius: 2px; 4186 padding: 4px 7px; 4187 font-size: 15px; 4188 color: rgba(0, 0, 0, 0.6); 4189} 4190 4191pre code { 4192 display: block; 4193 border-left: 2px solid rgba(0, 0, 0, .1); 4194 padding: 0 0 0 36px; 4195} 4196 4197${css} 4198</style> 4199 4200<code id="code-container"></code> 4201 4202`); 4203 4204 class Code extends Mutating(T$4(HTMLElement)) { 4205 4206 renderContent() { 4207 4208 // check if language can be highlighted 4209 this.languageName = this.getAttribute('language'); 4210 if (!this.languageName) { 4211 console.warn('You need to provide a language attribute to your <d-code>
4211 block to let us know how to highlight your code; e.g.:\n <d-code language="python">zeros = np.zeros(shape)</d-code>.'); 4212 return; 4213 } 4214 const language = prism.languages[this.languageName]; 4215 if (language == undefined) { 4216 console.warn(`Distill does not yet support highlighting your code block in "${this.languageName}'.`); 4217 return; 4218 } 4219 4220 let content = this.textContent; 4221 const codeTag = this.shadowRoot.querySelector('#code-container'); 4222 4223 if (this.hasAttribute('block')) { 4224 // normalize the tab indents 4225 content = content.replace(/\n/, ''); 4226 const tabs = content.match(/\s*/); 4227 content = content.replace(new RegExp('\n' + tabs, 'g'), '\n'); 4228 content = content.trim(); 4229 // wrap code block in pre tag if needed 4230 if (codeTag.parentNode instanceof ShadowRoot) { 4231 const preTag = document.createElement('pre'); 4232 this.shadowRoot.removeChild(codeTag); 4233 preTag.appendChild(codeTag); 4234 this.shadowRoot.appendChild(preTag); 4235 } 4236 4237 } 4238 4239 codeTag.className = `language-${this.languageName}`; 4240 codeTag.innerHTML = prism.highlight(content, language); 4241 } 4242 4243 } 4244 4245 // Copyright 2018 The Distill Template Authors 4246 4247 const T$5 = Template('d-footnote', ` 4248<style> 4249 4250d-math[block] { 4251 display: block; 4252} 4253 4254:host { 4255 4256} 4257 4258sup { 4259 line-height: 1em; 4260 font-size: 0.75em; 4261 position: relative; 4262 top: -.5em; 4263 vertical-align: baseline; 4264} 4265 4266span { 4267 color: hsla(206, 90%, 20%, 0.7); 4268 cursor: default; 4269} 4270 4271.footnote-container { 4272 padding: 10px; 4273} 4274 4275</style> 4276 4277<d-hover-box> 4278 <div class="footnote-container"> 4279 <slot id="slot"></slot> 4280 </div> 4281</d-hover-box> 4282 4283<sup> 4284 <span id="fn-" data-hover-ref=""></span> 4285</sup> 4286 4287`); 4288 4289 class Footnote extends T$5(HTMLElement) { 4290 4291 constructor() { 4292 super(); 4293 4294 const options = {childList: true, characterData: true, subtree: true}; 4295 const observer = new MutationObserver(this.notify); 4296 observer.observe(this, options); 4297 } 4298 4299 notify() { 4300 const options = { detail: this, bubbles: true }; 4301 const event = new CustomEvent('onFootnoteChanged', options); 4302 document.dispatchEvent(event); 4303 } 4304 4305 connectedCallback() { 4306 // listen and notify about changes to slotted content 4307 // const slot = this.shadowRoot.querySelector('#slot'); 4308 // console.warn(slot.textContent); 4309 // slot.addEventListener('slotchange', this.notify); 4310 this.hoverBox = this.root.querySelector('d-hover-box'); 4311 window.customElements.whenDefined('d-hover-box').then(() => { 4312 this.hoverBox.listen(this); 4313 }); 4314 // create numeric ID 4315 Footnote.currentFootnoteId += 1; 4316 const IdString = Footnote.currentFootnoteId.toString(); 4317 this.root.host.id = 'd-footnote-' + IdString; 4318 4319 // set up hidden hover box 4320 const id = 'dt-fn-hover-box-' + IdString; 4321 this.hoverBox.id = id; 4322 4323 // set up visible footnote marker 4324 const span = this.root.querySelector('#fn-'); 4325 span.setAttribute('id', 'fn-' + IdString); 4326 span.setAttribute('data-hover-ref', id); 4327 span.textContent = IdString; 4328 } 4329 4330 } 4331 4332 Footnote.currentFootnoteId = 0; 4333 4334 // Copyright 2018 The Distill Template Authors 4335 4336 const T$6 = Template('d-footnote-list', ` 4337<style> 4338 4339d-footnote-list { 4340 contain: layout style; 4341} 4342 4343d-footnote-list > * { 4344 grid-column: text; 4345} 4346 4347d-footnote-list a.footnote-backlink { 4348 color: rgba(0,0,0,0.3); 4349 padding-left: 0.5em; 4350} 4351 4352</style> 4353 4354<h3>Footnotes</h3> 4355<ol></ol> 4356`, false); 4357 4358 class FootnoteList extends T$6(HTMLElement) { 4359 4360 connectedCallback() { 4361 super.connectedCallback(); 4362 4363 this.list = this.root.querySelector('ol'); 4364 // footnotes list is initially hidden 4365 this.root.style.display = 'none'; 4366 // look through document and register existing footnotes 4367 // Store.subscribeTo('footnotes', (footnote) => { 4368 // this.renderFootnote(footnote); 4369 // }); 4370 } 4371 4372 // TODO: could optimize this to accept individual footnotes? 4373 set footnotes(footnotes) { 4374 this.list.innerHTML = ''; 4375 if (footnotes.length) { 4376 // ensure footnote list is visible 4377 this.root.style.display = ''; 4378 4379 for (const footnote of footnotes) { 4380 // construct and append list item to show footnote 4381 const listItem = document.createElement('li'); 4382 listItem.id = footnote.id + '-listing'; 4383 listItem.innerHTML = footnote.innerHTML; 4384 4385 const backlink = document.createElement('a');
4386 backlink.setAttribute('class', 'footnote-backlink'); 4387 backlink.textContent = '[â©]'; 4388 backlink.href = '#' + footnote.id; 4389 4390 listItem.appendChild(backlink); 4391 this.list.appendChild(listItem); 4392 } 4393 } else { 4394 // ensure footnote list is invisible 4395 this.root.style.display = 'none'; 4396 } 4397 } 4398 4399 } 4400 4401 // Copyright 2018 The Distill Template Authors 4402 4403 const T$7 = Template('d-hover-box', ` 4404<style> 4405 4406:host { 4407 position: absolute; 4408 width: 100%; 4409 left: 0px; 4410 z-index: 10000; 4411 display: none; 4412 white-space: normal 4413} 4414 4415.container { 4416 position: relative; 4417 width: 704px; 4418 max-width: 100vw; 4419 margin: 0 auto; 4420} 4421 4422.panel { 4423 position: absolute; 4424 font-size: 1rem; 4425 line-height: 1.5em; 4426 top: 0; 4427 left: 0; 4428 width: 100%; 4429 border: 1px solid rgba(0, 0, 0, 0.1); 4430 background-color: rgba(250, 250, 250, 0.95); 4431 box-shadow: 0 0 7px rgba(0, 0, 0, 0.1); 4432 border-radius: 4px; 4433 box-sizing: border-box; 4434 4435 backdrop-filter: blur(2px); 4436 -webkit-backdrop-filter: blur(2px); 4437} 4438 4439</style> 4440 4441<div class="container"> 4442 <div class="panel"> 4443 <slot></slot> 4444 </div> 4445</div> 4446`); 4447 4448 class HoverBox extends T$7(HTMLElement) { 4449 4450 constructor() { 4451 super(); 4452 } 4453 4454 connectedCallback() { 4455 4456 } 4457 4458 listen(element) { 4459 // console.log(element) 4460 this.bindDivEvents(this); 4461 this.bindTriggerEvents(element); 4462 // this.style.display = "block"; 4463 } 4464 4465 bindDivEvents(element) { 4466 // For mice, same behavior as hovering on links 4467 element.addEventListener('mouseover', () => { 4468 if (!this.visible) this.showAtNode(element); 4469 this.stopTimeout(); 4470 }); 4471 element.addEventListener('mouseout', () => { 4472 this.extendTimeout(500); 4473 }); 4474 // Don't trigger body touchstart event when touching within box 4475 element.addEventListener('touchstart', (event) => { 4476 event.stopPropagation(); 4477 }, {passive: true}); 4478 // Close box when touching outside box 4479 document.body.addEventListener('touchstart', () => { 4480 this.hide(); 4481 }, {passive: true}); 4482 } 4483 4484 bindTriggerEvents(node) { 4485 node.addEventListener('mouseover', () => { 4486 if (!this.visible) { 4487 this.showAtNode(node); 4488 } 4489 this.stopTimeout(); 4490 }); 4491 4492 node.addEventListener('mouseout', () => { 4493 this.extendTimeout(300); 4494 }); 4495 4496 node.addEventListener('touchstart', (event) => { 4497 if (this.visible) { 4498 this.hide(); 4499 } else { 4500 this.showAtNode(node); 4501 } 4502 // Don't trigger body touchstart event when touching link 4503 event.stopPropagation(); 4504 }, {passive: true}); 4505 } 4506 4507 show(position) { 4508 this.visible = true; 4509 this.style.display = 'block'; 4510 // 10px extra offset from element 4511 this.style.top = Math.round(position[1] + 10) + 'px'; 4512 } 4513 4514 showAtNode(node) { 4515 // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop 4516 const bbox = node.getBoundingClientRect(); 4517 this.show([node.offsetLeft + bbox.width, node.offsetTop + bbox.height]); 4518 } 4519 4520 hide() { 4521 this.visible = false; 4522 this.style.display = 'none'; 4523 this.stopTimeout(); 4524 } 4525 4526 stopTimeout() { 4527 if (this.timeout) { 4528 clearTimeout(this.timeout); 4529 } 4530 } 4531 4532 extendTimeout(time) { 4533 this.stopTimeout(); 4534 this.timeout = setTimeout(() => { 4535 this.hide(); 4536 }, time); 4537 } 4538 4539 } 4540 4541 // Copyright 2018 The Distill Template Authors 4542 // 4543 // Licensed under the Apache License, Version 2.0 (the "License"); 4544 // you may not use this file except in compliance with the License. 4545 // You may obtain a copy of the License at 4546 // 4547 // http://www.apache.org/licenses/LICENSE-2.0 4548 // 4549 // Unless required by applicable law or agreed to in writing, software 4550 // distributed under the License is distributed on an "AS IS" BASIS, 4551 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 4552 // See the License for the specific language governing permissions and 4553 // limitations under the License. 4554 4555 class Title extends HTMLElement { 4556 static get is() { return 'd-title'; } 4557 } 4558 4559 // Copyright 2018 The Distill Template Authors 4560 4561 const T$8 = Template('d-references', ` 4562<style> 4563d-references { 4564 display: block; 4565} 4566</style> 4567`, false); 4568 4569 class References extends T$8(HTMLElement) { 4570 4571 } 4572 4573 // Copyright 2018 The Distill Template Authors 4574 // 4575 // Licensed under the Apache License, Version 2.0 (the "License");
4576 // you may not use this file except in compliance with the License. 4577 // You may obtain a copy of the License at 4578 // 4579 // http://www.apache.org/licenses/LICENSE-2.0 4580 // 4581 // Unless required by applicable law or agreed to in writing, software 4582 // distributed under the License is distributed on an "AS IS" BASIS, 4583 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 4584 // See the License for the specific language governing permissions and 4585 // limitations under the License. 4586 4587 class TOC extends HTMLElement { 4588 4589 static get is() { return 'd-toc'; } 4590 4591 connectedCallback() { 4592 if (!this.getAttribute('prerendered')) { 4593 window.onload = () => { 4594 const article = document.querySelector('d-article'); 4595 const headings = article.querySelectorAll('h2, h3'); 4596 renderTOC(this, headings); 4597 }; 4598 } 4599 } 4600 4601 } 4602 4603 function renderTOC(element, headings) { 4604 4605 let ToC =` 4606 <style> 4607 4608 d-toc { 4609 contain: layout style; 4610 display: block; 4611 } 4612 4613 d-toc ul { 4614 padding-left: 0; 4615 } 4616 4617 d-toc ul > ul { 4618 padding-left: 24px; 4619 } 4620 4621 d-toc a { 4622 border-bottom: none; 4623 text-decoration: none; 4624 } 4625 4626 </style> 4627 <nav role="navigation" class="table-of-contents"></nav> 4628 <h2>Table of contents</h2> 4629 <ul>`; 4630 4631 for (const el of headings) { 4632 // should element be included in TOC? 4633 const isInTitle = el.parentElement.tagName == 'D-TITLE'; 4634 const isException = el.getAttribute('no-toc'); 4635 if (isInTitle || isException) continue; 4636 // create TOC entry 4637 const title = el.textContent; 4638 const link = '#' + el.getAttribute('id'); 4639 4640 let newLine = '<li>' + '<a href="' + link + '">' + title + '</a>' + '</li>'; 4641 if (el.tagName == 'H3') { 4642 newLine = '<ul>' + newLine + '</ul>'; 4643 } else { 4644 newLine += '<br>'; 4645 } 4646 ToC += newLine; 4647 4648 } 4649 4650 ToC += '</ul></nav>'; 4651 element.innerHTML = ToC; 4652 } 4653 4654 // Copyright 2018 The Distill Template Authors 4655 // 4656 // Licensed under the Apache License, Version 2.0 (the "License"); 4657 // you may not use this file except in compliance with the License. 4658 // You may obtain a copy of the License at 4659 // 4660 // http://www.apache.org/licenses/LICENSE-2.0 4661 // 4662 // Unless required by applicable law or agreed to in writing, software 4663 // distributed under the License is distributed on an "AS IS" BASIS, 4664 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 4665 // See the License for the specific language governing permissions and 4666 // limitations under the License. 4667 4668 // Figure 4669 // 4670 // d-figure provides a state-machine of visibility events: 4671 // 4672 // scroll out of view 4673 // +----------------+ 4674 // *do work here* | | 4675 // +----------------+ +-+---------+ +-v---------+ 4676 // | ready +----> onscreen | | offscreen | 4677 // +----------------+ +---------^-+ +---------+-+ 4678 // | | 4679 // +----------------+ 4680 // scroll into view 4681 // 4682 4683 class Figure extends HTMLElement { 4684 4685 static get is() { return 'd-figure'; } 4686 4687 static get readyQueue() { 4688 if (!Figure._readyQueue) { 4689 Figure._readyQueue = []; 4690 } 4691 return Figure._readyQueue; 4692 } 4693 4694 static addToReadyQueue(figure) { 4695 if (Figure.readyQueue.indexOf(figure) === -1) { 4696 Figure.readyQueue.push(figure); 4697 Figure.runReadyQueue(); 4698 } 4699 } 4700 4701 static runReadyQueue() { 4702 // console.log("Checking to run readyQueue, length: " + Figure.readyQueue.length + ", scrolling: " + Figure.isScrolling); 4703 // if (Figure.isScrolling) return; 4704 // console.log("Running ready Queue"); 4705 const figure = Figure.readyQueue 4706 .sort((a,b) => a._seenOnScreen - b._seenOnScreen ) 4707 .filter((figure) => !figure._ready) 4708 .pop(); 4709 if (figure) { 4710 figure.ready(); 4711 requestAnimationFrame(Figure.runReadyQueue); 4712 } 4713 4714 } 4715 4716 constructor() { 4717 super(); 4718 // debugger 4719 this._ready = false;
4720 this._onscreen = false; 4721 this._offscreen = true; 4722 } 4723 4724 connectedCallback() { 4725 this.loadsWhileScrolling = this.hasAttribute('loadsWhileScrolling'); 4726 Figure.marginObserver.observe(this); 4727 Figure.directObserver.observe(this); 4728 } 4729 4730 disconnectedCallback() { 4731 Figure.marginObserver.unobserve(this); 4732 Figure.directObserver.unobserve(this); 4733 } 4734 4735 // We use two separate observers: 4736 // One with an extra 1000px margin to warn if the viewpoint gets close, 4737 // And one for the actual on/off screen events 4738 4739 static get marginObserver() { 4740 if (!Figure._marginObserver) { 4741 // if (!('IntersectionObserver' in window)) { 4742 // throw new Error('no interscetionobbserver!'); 4743 // } 4744 const viewportHeight = window.innerHeight; 4745 const margin = Math.floor(2 * viewportHeight); 4746 const options = {rootMargin: margin + 'px 0px ' + margin + 'px 0px', threshold: 0.01}; 4747 const callback = Figure.didObserveMarginIntersection; 4748 const observer = new IntersectionObserver(callback, options); 4749 Figure._marginObserver = observer; 4750 } 4751 return Figure._marginObserver; 4752 } 4753 4754 static didObserveMarginIntersection(entries) { 4755 for (const entry of entries) { 4756 const figure = entry.target; 4757 if (entry.isIntersecting && !figure._ready) { 4758 Figure.addToReadyQueue(figure); 4759 } 4760 } 4761 } 4762 4763 static get directObserver() { 4764 if (!Figure._directObserver) { 4765 Figure._directObserver = new IntersectionObserver( 4766 Figure.didObserveDirectIntersection, { 4767 rootMargin: '0px', threshold: [0, 1.0], 4768 } 4769 ); 4770 } 4771 return Figure._directObserver; 4772 } 4773 4774 static didObserveDirectIntersection(entries) { 4775 for (const entry of entries) { 4776 const figure = entry.target; 4777 if (entry.isIntersecting) { 4778 figure._seenOnScreen = new Date(); 4779 // if (!figure._ready) { figure.ready(); } 4780 if (figure._offscreen) { figure.onscreen(); } 4781 } else { 4782 if (figure._onscreen) { figure.offscreen(); } 4783 } 4784 } 4785 } 4786 4787 // Notify listeners that registered late, too: 4788 4789 addEventListener(eventName, callback) { 4790 super.addEventListener(eventName, callback); 4791 // if we had already dispatched something while presumingly no one was listening, we do so again 4792 // debugger 4793 if (eventName === 'ready') { 4794 if (Figure.readyQueue.indexOf(this) !== -1) { 4795 this._ready = false; 4796 Figure.runReadyQueue(); 4797 } 4798 } 4799 if (eventName === 'onscreen') { 4800 this.onscreen(); 4801 } 4802 } 4803 4804 // Custom Events 4805 4806 ready() { 4807 // debugger 4808 this._ready = true; 4809 Figure.marginObserver.unobserve(this); 4810 const event = new CustomEvent('ready'); 4811 this.dispatchEvent(event); 4812 } 4813 4814 onscreen() { 4815 this._onscreen = true; 4816 this._offscreen = false; 4817 const event = new CustomEvent('onscreen'); 4818 this.dispatchEvent(event); 4819 } 4820 4821 offscreen() { 4822 this._onscreen = false; 4823 this._offscreen = true; 4824 const event = new CustomEvent('offscreen'); 4825 this.dispatchEvent(event); 4826 } 4827 4828 } 4829 4830 if (typeof window !== 'undefined') { 4831 4832 Figure.isScrolling = false; 4833 let timeout; 4834 const resetTimer = () => { 4835 Figure.isScrolling = true; 4836 clearTimeout(timeout); 4837 timeout = setTimeout(() => { 4838 Figure.isScrolling = false; 4839 Figure.runReadyQueue(); 4840 }, 500); 4841 }; 4842 window.addEventListener('scroll', resetTimer, true); 4843 4844 } 4845 4846 // Copyright 2018 The Distill Template Authors 4847 4848 // This overlay is not secure. 4849 // It is only meant as a social deterrent. 4850 4851 const productionHostname = 'distill.pub'; 4852 const T$9 = Template('d-interstitial', ` 4853<style> 4854 4855.overlay { 4856 position: fixed; 4857 width: 100%; 4858 height: 100%; 4859 top: 0; 4860 left: 0; 4861 background: white; 4862 4863 opacity: 1; 4864 visibility: visible; 4865 4866 display: flex; 4867 flex-flow: column; 4868 justify-content: center; 4869 z-index: 2147483647 /* MaxInt32 */ 4870 4871} 4872 4873.container { 4874 position: relative; 4875 margin-left: auto; 4876 margin-right: auto; 4877 max-width: 420px; 4878 padding: 2em; 4879} 4880 4881h1 { 4882 text-decoration: underline; 4883 text-decoration-color: hsl(0,100%,40%); 4884 -webkit-text-decoration-color: hsl(0,100%,40%); 4885 margin-bottom: 1em; 4886 line-height: 1.5em; 4887} 4888 4889input[type="password"] { 4890 -webkit-appearance: none; 4891 -moz-appearance: none; 4892 appearance: none; 4893 -webkit-box-shadow: none; 4894 -moz-box-shadow: none; 4895 box-shadow: none; 4896 -webkit-border-radius: none; 4897 -moz-border-radius: none; 4898 -ms-border-radius: none; 4899 -o-border-radius: none; 4900 border-radius: none; 4901 outline: none; 4902 4903 font-size: 18px; 4904 background: none; 4905 width: 25%; 4906 padding: 10px; 4907 border: none; 4908 border-bottom: solid 2px #999; 4909 transition: border .3s; 4910} 4911 4912input[type="password"]:focus { 4913 border-bottom: solid 2px #333; 4914} 4915 4916input[type="password"].wrong { 4917 border-bottom: solid 2px hsl(0,100%,40%); 4918} 4919 4920p small { 4921 color: #888; 4922} 4923 4924.logo { 4925 position: relative; 4926 font-size: 1.5em; 4927 margin-bottom: 3em; 4928} 4929 4930.logo svg { 4931 width: 36px; 4932 position: relative; 4933 top: 6px; 4934 margin-right: 2px; 4935} 4936 4937.logo svg path { 4938 fill: none; 4939 stroke: black; 4940 stroke-width: 2px; 4941} 4942 4943</style> 4944 4945<div class="overlay"> 4946 <div class="container"> 4947 <h1>This article is in review.</h1> 4948 <p>
4948Do not share this URL or the contents of this article. Thank you!</p> 4949 <input id="interstitial-password-input" type="password" name="password" autofocus/> 4950 <p><small>Enter the password we shared with you as part of the review process to view the article.</small></p> 4951 </div> 4952</div> 4953`); 4954 4955 class Interstitial extends T$9(HTMLElement) { 4956 4957 connectedCallback() { 4958 if (this.shouldRemoveSelf()) { 4959 this.parentElement.removeChild(this); 4960 } else { 4961 const passwordInput = this.root.querySelector('#interstitial-password-input'); 4962 passwordInput.oninput = (event) => this.passwordChanged(event); 4963 } 4964 } 4965 4966 passwordChanged(event) { 4967 const entered = event.target.value; 4968 if (entered === this.password) { 4969 console.log('Correct password entered.'); 4970 this.parentElement.removeChild(this); 4971 if (typeof(Storage) !== 'undefined') { 4972 console.log('Saved that correct password was entered.'); 4973 localStorage.setItem(this.localStorageIdentifier(), 'true'); 4974 } 4975 } 4976 } 4977 4978 shouldRemoveSelf() { 4979 // should never be visible in production 4980 if (window && window.location.hostname === productionHostname) { 4981 console.warn('Interstitial found on production, hiding it.'); 4982 return true 4983 } 4984 // should only have to enter password once 4985 if (typeof(Storage) !== 'undefined') { 4986 if (localStorage.getItem(this.localStorageIdentifier()) === 'true') { 4987 console.log('Loaded that correct password was entered before; skipping interstitial.'); 4988 return true; 4989 } 4990 } 4991 // otherwise, leave visible 4992 return false; 4993 } 4994 4995 localStorageIdentifier() { 4996 const prefix = 'distill-drafts'; 4997 const suffix = 'interstitial-password-correct'; 4998 return prefix + (window ? window.location.pathname : '-') + suffix 4999 } 5000 5001 } 5002 5003 function ascending(a, b) { 5004 return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; 5005 } 5006 5007 function bisector(compare) { 5008 if (compare.length === 1) compare = ascendingComparator(compare); 5009 return { 5010 left: function(a, x, lo, hi) { 5011 if (lo == null) lo = 0; 5012 if (hi == null) hi = a.length; 5013 while (lo < hi) { 5014 var mid = lo + hi >>> 1; 5015 if (compare(a[mid], x) < 0) lo = mid + 1; 5016 else hi = mid; 5017 } 5018 return lo; 5019 }, 5020 right: function(a, x, lo, hi) { 5021 if (lo == null) lo = 0; 5022 if (hi == null) hi = a.length; 5023 while (lo < hi) { 5024 var mid = lo + hi >>> 1; 5025 if (compare(a[mid], x) > 0) hi = mid; 5026 else lo = mid + 1; 5027 } 5028 return lo; 5029 } 5030 }; 5031 } 5032 5033 function ascendingComparator(f) { 5034 return function(d, x) { 5035 return ascending(f(d), x); 5036 }; 5037 } 5038 5039 var ascendingBisect = bisector(ascending); 5040 var bisectRight = ascendingBisect.right; 5041 5042 function range(start, stop, step) { 5043 start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step; 5044 5045 var i = -1, 5046 n = Math.max(0, Math.ceil((stop - start) / step)) | 0, 5047 range = new Array(n); 5048 5049 while (++i < n) { 5050 range[i] = start + i * step; 5051 } 5052 5053 return range; 5054 } 5055 5056 var e10 = Math.sqrt(50), 5057 e5 = Math.sqrt(10), 5058 e2 = Math.sqrt(2); 5059 5060 function ticks(start, stop, count) { 5061 var reverse, 5062 i = -1, 5063 n, 5064 ticks, 5065 step; 5066 5067 stop = +stop, start = +start, count = +count; 5068 if (start === stop && count > 0) return [start]; 5069 if (reverse = stop < start) n = start, start = stop, stop = n; 5070 if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return []; 5071 5072 if (step > 0) { 5073 start = Math.ceil(start / step); 5074 stop = Math.floor(stop / step); 5075 ticks = new Array(n = Math.ceil(stop - start + 1)); 5076 while (++i < n) ticks[i] = (start + i) * step; 5077 } else { 5078 start = Math.floor(start * step); 5079 stop = Math.ceil(stop * step); 5080 ticks = new Array(n = Math.ceil(start - stop + 1)); 5081 while (++i < n) ticks[i] = (start - i) / step; 5082 } 5083 5084 if (reverse) ticks.reverse(); 5085 5086 return ticks; 5087 } 5088 5089 function tickIncrement(start, stop, count) { 5090 var step = (stop - start) / Math.max(0, count), 5091 power = Math.floor(Math.log(step) / Math.LN10), 5092 error = step / Math.pow(10, power); 5093 return power >= 0 5094 ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power) 5095 : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1); 5096 } 5097 5098 function tickStep(start, stop, count) { 5099 var step0 = Math.abs(stop - start) / Math.max(0, count), 5100 step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)), 5101 error = step0 / step1; 5102 if (error >= e10) step1 *= 10; 5103 else if (error >= e5) step1 *= 5; 5104 else if (error >= e2) step1 *= 2; 5105 return stop < start ? -step1 : step1; 5106 } 5107 5108 function initRange(domain, range) { 5109 switch (arguments.length) { 5110 case 0: break; 5111 case 1: this.range(domain); break; 5112 default: this.range(range).domain(domain); break; 5113 } 5114 return this; 5115 } 5116 5117 function define(constructor, factory, prototype) { 5118 constructor.prototype = factory.prototype = prototype; 5119 prototype.constructor = constructor; 5120 } 5121 5122 function extend(parent, definition) { 5123 var prototype = Object.create(parent.prototype); 5124 for (var key in definition) prototype[key] = definition[key]; 5125 return prototype; 5126 } 5127 5128 function Color() {} 5129 5130 var darker = 0.7; 5131 var brighter = 1 / darker; 5132 5133 var reI = "\\s*([+-]?\\d+)\\s*", 5134 reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*", 5135 reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*", 5136 reHex = /^#([0-9a-f]{3,8})$/, 5137 reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"), 5138 reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"), 5139 reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"), 5140 reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"), 5141 reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"), 5142 reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$"); 5143 5144 var named = {
vendor: 4,355 bytes, lines 5145-5322
5145 aliceblue: 0xf0f8ff, 5146 antiquewhite: 0xfaebd7, 5147 aqua: 0x00ffff, 5148 aquamarine: 0x7fffd4, 5149 azure: 0xf0ffff, 5150 beige: 0xf5f5dc, 5151 bisque: 0xffe4c4, 5152 black: 0x000000, 5153 blanchedalmond: 0xffebcd, 5154 blue: 0x0000ff, 5155 blueviolet: 0x8a2be2, 5156 brown: 0xa52a2a, 5157 burlywood: 0xdeb887, 5158 cadetblue: 0x5f9ea0, 5159 chartreuse: 0x7fff00, 5160 chocolate: 0xd2691e, 5161 coral: 0xff7f50, 5162 cornflowerblue: 0x6495ed, 5163 cornsilk: 0xfff8dc, 5164 crimson: 0xdc143c, 5165 cyan: 0x00ffff, 5166 darkblue: 0x00008b, 5167 darkcyan: 0x008b8b, 5168 darkgoldenrod: 0xb8860b, 5169 darkgray: 0xa9a9a9, 5170 darkgreen: 0x006400, 5171 darkgrey: 0xa9a9a9, 5172 darkkhaki: 0xbdb76b, 5173 darkmagenta: 0x8b008b, 5174 darkolivegreen: 0x556b2f, 5175 darkorange: 0xff8c00, 5176 darkorchid: 0x9932cc, 5177 darkred: 0x8b0000, 5178 darksalmon: 0xe9967a, 5179 darkseagreen: 0x8fbc8f, 5180 darkslateblue: 0x483d8b, 5181 darkslategray: 0x2f4f4f, 5182 darkslategrey: 0x2f4f4f, 5183 darkturquoise: 0x00ced1, 5184 darkviolet: 0x9400d3, 5185 deeppink: 0xff1493, 5186 deepskyblue: 0x00bfff, 5187 dimgray: 0x696969, 5188 dimgrey: 0x696969, 5189 dodgerblue: 0x1e90ff, 5190 firebrick: 0xb22222, 5191 floralwhite: 0xfffaf0, 5192 forestgreen: 0x228b22, 5193 fuchsia: 0xff00ff, 5194 gainsboro: 0xdcdcdc, 5195 ghostwhite: 0xf8f8ff, 5196 gold: 0xffd700, 5197 goldenrod: 0xdaa520, 5198 gray: 0x808080, 5199 green: 0x008000, 5200 greenyellow: 0xadff2f, 5201 grey: 0x808080, 5202 honeydew: 0xf0fff0, 5203 hotpink: 0xff69b4, 5204 indianred: 0xcd5c5c, 5205 indigo: 0x4b0082, 5206 ivory: 0xfffff0, 5207 khaki: 0xf0e68c, 5208 lavender: 0xe6e6fa, 5209 lavenderblush: 0xfff0f5, 5210 lawngreen: 0x7cfc00, 5211 lemonchiffon: 0xfffacd, 5212 lightblue: 0xadd8e6, 5213 lightcoral: 0xf08080, 5214 lightcyan: 0xe0ffff, 5215 lightgoldenrodyellow: 0xfafad2, 5216 lightgray: 0xd3d3d3, 5217 lightgreen: 0x90ee90, 5218 lightgrey: 0xd3d3d3, 5219 lightpink: 0xffb6c1, 5220 lightsalmon: 0xffa07a, 5221 lightseagreen: 0x20b2aa, 5222 lightskyblue: 0x87cefa, 5223 lightslategray: 0x778899, 5224 lightslategrey: 0x778899, 5225 lightsteelblue: 0xb0c4de, 5226 lightyellow: 0xffffe0, 5227 lime: 0x00ff00, 5228 limegreen: 0x32cd32, 5229 linen: 0xfaf0e6, 5230 magenta: 0xff00ff, 5231 maroon: 0x800000, 5232 mediumaquamarine: 0x66cdaa, 5233 mediumblue: 0x0000cd, 5234 mediumorchid: 0xba55d3, 5235 mediumpurple: 0x9370db, 5236 mediumseagreen: 0x3cb371, 5237 mediumslateblue: 0x7b68ee, 5238 mediumspringgreen: 0x00fa9a, 5239 mediumturquoise: 0x48d1cc, 5240 mediumvioletred: 0xc71585, 5241 midnightblue: 0x191970, 5242 mintcream: 0xf5fffa, 5243 mistyrose: 0xffe4e1, 5244 moccasin: 0xffe4b5, 5245 navajowhite: 0xffdead, 5246 navy: 0x000080, 5247 oldlace: 0xfdf5e6, 5248 olive: 0x808000, 5249 olivedrab: 0x6b8e23, 5250 orange: 0xffa500, 5251 orangered: 0xff4500, 5252 orchid: 0xda70d6, 5253 palegoldenrod: 0xeee8aa, 5254 palegreen: 0x98fb98, 5255 paleturquoise: 0xafeeee, 5256 palevioletred: 0xdb7093, 5257 papayawhip: 0xffefd5, 5258 peachpuff: 0xffdab9, 5259 peru: 0xcd853f, 5260 pink: 0xffc0cb, 5261 plum: 0xdda0dd, 5262 powderblue: 0xb0e0e6, 5263 purple: 0x800080, 5264 rebeccapurple: 0x663399, 5265 red: 0xff0000, 5266 rosybrown: 0xbc8f8f, 5267 royalblue: 0x4169e1, 5268 saddlebrown: 0x8b4513, 5269 salmon: 0xfa8072, 5270 sandybrown: 0xf4a460, 5271 seagreen: 0x2e8b57, 5272 seashell: 0xfff5ee, 5273 sienna: 0xa0522d, 5274 silver: 0xc0c0c0, 5275 skyblue: 0x87ceeb, 5276 slateblue: 0x6a5acd, 5277 slategray: 0x708090, 5278 slategrey: 0x708090, 5279 snow: 0xfffafa, 5280 springgreen: 0x00ff7f, 5281 steelblue: 0x4682b4, 5282 tan: 0xd2b48c, 5283 teal: 0x008080, 5284 thistle: 0xd8bfd8, 5285 tomato: 0xff6347, 5286 turquoise: 0x40e0d0, 5287 violet: 0xee82ee, 5288 wheat: 0xf5deb3, 5289 white: 0xffffff, 5290 whitesmoke: 0xf5f5f5, 5291 yellow: 0xffff00, 5292 yellowgreen: 0x9acd32 5293 }; 5294 5295 define(Color, color, { 5296 copy: function(channels) { 5297 return Object.assign(new this.constructor, this, channels); 5298 }, 5299 displayable: function() { 5300 return this.rgb().displayable(); 5301 }, 5302 hex: color_formatHex, // Deprecated! Use color.formatHex. 5303 formatHex: color_formatHex, 5304 formatHsl: color_formatHsl, 5305 formatRgb: color_formatRgb, 5306 toString: color_formatRgb 5307 }); 5308 5309 function color_formatHex() { 5310 return this.rgb().formatHex(); 5311 } 5312 5313 function color_formatHsl() { 5314 return hslConvert(this).formatHsl(); 5315 } 5316 5317 function color_formatRgb() { 5318 return this.rgb().formatRgb(); 5319 } 5320 5321 function color(format) { 5322 var m, l;
vendor: 5,833 bytes, lines 5323-5484
5323 format = (format + "").trim().toLowerCase(); 5324 return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000 5325 : l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00 5326 : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000 5327 : l === 4 ? rgba((m >> 12 & 0xf) | (m >> 8 & 0xf0), (m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), (((m & 0xf) << 4) | (m & 0xf)) / 0xff) // #f000 5328 : null) // invalid hex 5329 : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0) 5330 : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%) 5331 : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1) 5332 : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1) 5333 : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%) 5334 : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1) 5335 : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins 5336 : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) 5337 : null; 5338 } 5339 5340 function rgbn(n) { 5341 return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1); 5342 } 5343 5344 function rgba(r, g, b, a) { 5345 if (a <= 0) r = g = b = NaN; 5346 return new Rgb(r, g, b, a); 5347 } 5348 5349 function rgbConvert(o) { 5350 if (!(o instanceof Color)) o = color(o); 5351 if (!o) return new Rgb; 5352 o = o.rgb(); 5353 return new Rgb(o.r, o.g, o.b, o.opacity); 5354 } 5355 5356 function rgb(r, g, b, opacity) { 5357 return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity); 5358 } 5359 5360 function Rgb(r, g, b, opacity) { 5361 this.r = +r; 5362 this.g = +g; 5363 this.b = +b; 5364 this.opacity = +opacity; 5365 } 5366 5367 define(Rgb, rgb, extend(Color, { 5368 brighter: function(k) { 5369 k = k == null ? brighter : Math.pow(brighter, k); 5370 return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); 5371 }, 5372 darker: function(k) { 5373 k = k == null ? darker : Math.pow(darker, k); 5374 return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); 5375 }, 5376 rgb: function() { 5377 return this; 5378 }, 5379 displayable: function() { 5380 return (-0.5 <= this.r && this.r < 255.5) 5381 && (-0.5 <= this.g && this.g < 255.5) 5382 && (-0.5 <= this.b && this.b < 255.5) 5383 && (0 <= this.opacity && this.opacity <= 1); 5384 }, 5385 hex: rgb_formatHex, // Deprecated! Use color.formatHex. 5386 formatHex: rgb_formatHex, 5387 formatRgb: rgb_formatRgb, 5388 toString: rgb_formatRgb 5389 })); 5390 5391 function rgb_formatHex() { 5392 return "#" + hex(this.r) + hex(this.g) + hex(this.b); 5393 } 5394 5395 function rgb_formatRgb() { 5396 var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); 5397 return (a === 1 ? "rgb(" : "rgba(") 5398 + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", " 5399 + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", " 5400 + Math.max(0, Math.min(255, Math.round(this.b) || 0)) 5401 + (a === 1 ? ")" : ", " + a + ")"); 5402 } 5403 5404 function hex(value) { 5405 value = Math.max(0, Math.min(255, Math.round(value) || 0)); 5406 return (value < 16 ? "0" : "") + value.toString(16); 5407 } 5408 5409 function hsla(h, s, l, a) { 5410 if (a <= 0) h = s = l = NaN; 5411 else if (l <= 0 || l >= 1) h = s = NaN; 5412 else if (s <= 0) h = NaN; 5413 return new Hsl(h, s, l, a); 5414 } 5415 5416 function hslConvert(o) { 5417 if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity); 5418 if (!(o instanceof Color)) o = color(o); 5419 if (!o) return new Hsl; 5420 if (o instanceof Hsl) return o; 5421 o = o.rgb(); 5422 var r = o.r / 255, 5423 g = o.g / 255, 5424 b = o.b / 255, 5425 min = Math.min(r, g, b), 5426 max = Math.max(r, g, b), 5427 h = NaN, 5428 s = max - min, 5429 l = (max + min) / 2; 5430 if (s) { 5431 if (r === max) h = (g - b) / s + (g < b) * 6; 5432 else if (g === max) h = (b - r) / s + 2; 5433 else h = (r - g) / s + 4; 5434 s /= l < 0.5 ? max + min : 2 - max - min; 5435 h *= 60; 5436 } else { 5437 s = l > 0 && l < 1 ? 0 : h; 5438 } 5439 return new Hsl(h, s, l, o.opacity); 5440 } 5441 5442 function hsl(h, s, l, opacity) { 5443 return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity); 5444 } 5445 5446 function Hsl(h, s, l, opacity) { 5447 this.h = +h; 5448 this.s = +s; 5449 this.l = +l; 5450 this.opacity = +opacity; 5451 } 5452 5453 define(Hsl, hsl, extend(Color, { 5454 brighter: function(k) { 5455 k = k == null ? brighter : Math.pow(brighter, k); 5456 return new Hsl(this.h, this.s, this.l * k, this.opacity); 5457 }, 5458 darker: function(k) { 5459 k = k == null ? darker : Math.pow(darker, k); 5460 return new Hsl(this.h, this.s, this.l * k, this.opacity); 5461 }, 5462 rgb: function() { 5463 var h = this.h % 360 + (this.h < 0) * 360, 5464 s = isNaN(h) || isNaN(this.s) ? 0 : this.s, 5465 l = this.l, 5466 m2 = l + (l < 0.5 ? l : 1 - l) * s, 5467 m1 = 2 * l - m2; 5468 return new Rgb( 5469 hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), 5470 hsl2rgb(h, m1, m2), 5471 hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), 5472 this.opacity 5473 ); 5474 }, 5475 displayable: function() { 5476 return (0 <= this.s && this.s <= 1 || isNaN(this.s)) 5477 && (0 <= this.l && this.l <= 1) 5478 && (0 <= this.opacity && this.opacity <= 1); 5479 }, 5480 formatHsl: function() { 5481 var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); 5482 return (a === 1 ? "hsl(" : "hsla(") 5483 + (this.h || 0) + ", " 5484 + (this.s || 0) * 100 + "%, "
vendor: 17,998 bytes, lines 5485-6113
5485 + (this.l || 0) * 100 + "%" 5486 + (a === 1 ? ")" : ", " + a + ")"); 5487 } 5488 })); 5489 5490 /* From FvD 13.37, CSS Color Module Level 3 */ 5491 function hsl2rgb(h, m1, m2) { 5492 return (h < 60 ? m1 + (m2 - m1) * h / 60 5493 : h < 180 ? m2 5494 : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 5495 : m1) * 255; 5496 } 5497 5498 var deg2rad = Math.PI / 180; 5499 var rad2deg = 180 / Math.PI; 5500 5501 // https://observablehq.com/@mbostock/lab-and-rgb 5502 var K = 18, 5503 Xn = 0.96422, 5504 Yn = 1, 5505 Zn = 0.82521, 5506 t0 = 4 / 29, 5507 t1 = 6 / 29, 5508 t2 = 3 * t1 * t1, 5509 t3 = t1 * t1 * t1; 5510 5511 function labConvert(o) { 5512 if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity); 5513 if (o instanceof Hcl) return hcl2lab(o); 5514 if (!(o instanceof Rgb)) o = rgbConvert(o); 5515 var r = rgb2lrgb(o.r), 5516 g = rgb2lrgb(o.g), 5517 b = rgb2lrgb(o.b), 5518 y = xyz2lab((0.2225045 * r + 0.7168786 * g + 0.0606169 * b) / Yn), x, z; 5519 if (r === g && g === b) x = z = y; else { 5520 x = xyz2lab((0.4360747 * r + 0.3850649 * g + 0.1430804 * b) / Xn); 5521 z = xyz2lab((0.0139322 * r + 0.0971045 * g + 0.7141733 * b) / Zn); 5522 } 5523 return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity); 5524 } 5525 5526 function lab(l, a, b, opacity) { 5527 return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity); 5528 } 5529 5530 function Lab(l, a, b, opacity) { 5531 this.l = +l; 5532 this.a = +a; 5533 this.b = +b; 5534 this.opacity = +opacity; 5535 } 5536 5537 define(Lab, lab, extend(Color, { 5538 brighter: function(k) { 5539 return new Lab(this.l + K * (k == null ? 1 : k), this.a, this.b, this.opacity); 5540 }, 5541 darker: function(k) { 5542 return new Lab(this.l - K * (k == null ? 1 : k), this.a, this.b, this.opacity); 5543 }, 5544 rgb: function() { 5545 var y = (this.l + 16) / 116, 5546 x = isNaN(this.a) ? y : y + this.a / 500, 5547 z = isNaN(this.b) ? y : y - this.b / 200; 5548 x = Xn * lab2xyz(x); 5549 y = Yn * lab2xyz(y); 5550 z = Zn * lab2xyz(z); 5551 return new Rgb( 5552 lrgb2rgb( 3.1338561 * x - 1.6168667 * y - 0.4906146 * z), 5553 lrgb2rgb(-0.9787684 * x + 1.9161415 * y + 0.0334540 * z), 5554 lrgb2rgb( 0.0719453 * x - 0.2289914 * y + 1.4052427 * z), 5555 this.opacity 5556 ); 5557 } 5558 })); 5559 5560 function xyz2lab(t) { 5561 return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0; 5562 } 5563 5564 function lab2xyz(t) { 5565 return t > t1 ? t * t * t : t2 * (t - t0); 5566 } 5567 5568 function lrgb2rgb(x) { 5569 return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055); 5570 } 5571 5572 function rgb2lrgb(x) { 5573 return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4); 5574 } 5575 5576 function hclConvert(o) { 5577 if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity); 5578 if (!(o instanceof Lab)) o = labConvert(o); 5579 if (o.a === 0 && o.b === 0) return new Hcl(NaN, 0 < o.l && o.l < 100 ? 0 : NaN, o.l, o.opacity); 5580 var h = Math.atan2(o.b, o.a) * rad2deg; 5581 return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity); 5582 } 5583 5584 function hcl(h, c, l, opacity) { 5585 return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity); 5586 } 5587 5588 function Hcl(h, c, l, opacity) { 5589 this.h = +h; 5590 this.c = +c; 5591 this.l = +l; 5592 this.opacity = +opacity; 5593 } 5594 5595 function hcl2lab(o) { 5596 if (isNaN(o.h)) return new Lab(o.l, 0, 0, o.opacity); 5597 var h = o.h * deg2rad; 5598 return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity); 5599 } 5600 5601 define(Hcl, hcl, extend(Color, { 5602 brighter: function(k) { 5603 return new Hcl(this.h, this.c, this.l + K * (k == null ? 1 : k), this.opacity); 5604 }, 5605 darker: function(k) { 5606 return new Hcl(this.h, this.c, this.l - K * (k == null ? 1 : k), this.opacity); 5607 }, 5608 rgb: function() { 5609 return hcl2lab(this).rgb(); 5610 } 5611 })); 5612 5613 var A = -0.14861, 5614 B = +1.78277, 5615 C = -0.29227, 5616 D = -0.90649, 5617 E = +1.97294, 5618 ED = E * D, 5619 EB = E * B, 5620 BC_DA = B * C - D * A; 5621 5622 function cubehelixConvert(o) { 5623 if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity); 5624 if (!(o instanceof Rgb)) o = rgbConvert(o); 5625 var r = o.r / 255, 5626 g = o.g / 255, 5627 b = o.b / 255, 5628 l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB), 5629 bl = b - l, 5630 k = (E * (g - l) - C * bl) / D, 5631 s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1 5632 h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN; 5633 return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity); 5634 } 5635 5636 function cubehelix(h, s, l, opacity) { 5637 return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity); 5638 } 5639 5640 function Cubehelix(h, s, l, opacity) { 5641 this.h = +h; 5642 this.s = +s; 5643 this.l = +l; 5644 this.opacity = +opacity; 5645 } 5646 5647 define(Cubehelix, cubehelix, extend(Color, { 5648 brighter: function(k) { 5649 k = k == null ? brighter : Math.pow(brighter, k); 5650 return new Cubehelix(this.h, this.s, this.l * k, this.opacity); 5651 }, 5652 darker: function(k) { 5653 k = k == null ? darker : Math.pow(darker, k); 5654 return new Cubehelix(this.h, this.s, this.l * k, this.opacity); 5655 }, 5656 rgb: function() { 5657 var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad, 5658 l = +this.l, 5659 a = isNaN(this.s) ? 0 : this.s * l * (1 - l), 5660 cosh = Math.cos(h), 5661 sinh = Math.sin(h); 5662 return new Rgb( 5663 255 * (l + a * (A * cosh + B * sinh)), 5664 255 * (l + a * (C * cosh + D * sinh)), 5665 255 * (l + a * (E * cosh)), 5666 this.opacity 5667 ); 5668 } 5669 })); 5670 5671 function constant(x) { 5672 return function() { 5673 return x; 5674 }; 5675 } 5676 5677 function linear(a, d) { 5678 return function(t) { 5679 return a + t * d; 5680 }; 5681 } 5682 5683 function exponential(a, b, y) { 5684 return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) { 5685 return Math.pow(a + t * b, y); 5686 }; 5687 } 5688 5689 function gamma(y) { 5690 return (y = +y) === 1 ? nogamma : function(a, b) { 5691 return b - a ? exponential(a, b, y) : constant(isNaN(a) ? b : a); 5692 }; 5693 } 5694 5695 function nogamma(a, b) { 5696 var d = b - a; 5697 return d ? linear(a, d) : constant(isNaN(a) ? b : a); 5698 } 5699 5700 var rgb$1 = (function rgbGamma(y) { 5701 var color = gamma(y); 5702 5703 function rgb$1(start, end) { 5704 var r = color((start = rgb(start)).r, (end = rgb(end)).r), 5705 g = color(start.g, end.g), 5706 b = color(start.b, end.b), 5707 opacity = nogamma(start.opacity, end.opacity); 5708 return function(t) { 5709 start.r = r(t); 5710 start.g = g(t); 5711 start.b = b(t); 5712 start.opacity = opacity(t); 5713 return start + ""; 5714 }; 5715 } 5716 5717 rgb$1.gamma = rgbGamma; 5718 5719 return rgb$1; 5720 })(1); 5721 5722 function numberArray(a, b) { 5723 if (!b) b = []; 5724 var n = a ? Math.min(b.length, a.length) : 0, 5725 c = b.slice(), 5726 i; 5727 return function(t) { 5728 for (i = 0; i < n; ++i) c[i] = a[i] * (1 - t) + b[i] * t; 5729 return c; 5730 }; 5731 } 5732 5733 function isNumberArray(x) { 5734 return ArrayBuffer.isView(x) && !(x instanceof DataView); 5735 } 5736 5737 function genericArray(a, b) { 5738 var nb = b ? b.length : 0, 5739 na = a ? Math.min(nb, a.length) : 0, 5740 x = new Array(na), 5741 c = new Array(nb), 5742 i; 5743 5744 for (i = 0; i < na; ++i) x[i] = interpolate(a[i], b[i]); 5745 for (; i < nb; ++i) c[i] = b[i]; 5746 5747 return function(t) { 5748 for (i = 0; i < na; ++i) c[i] = x[i](t); 5749 return c; 5750 }; 5751 } 5752 5753 function date(a, b) { 5754 var d = new Date; 5755 return a = +a, b = +b, function(t) { 5756 return d.setTime(a * (1 - t) + b * t), d; 5757 }; 5758 } 5759 5760 function interpolateNumber(a, b) { 5761 return a = +a, b = +b, function(t) { 5762 return a * (1 - t) + b * t; 5763 }; 5764 } 5765 5766 function object(a, b) { 5767 var i = {}, 5768 c = {}, 5769 k; 5770 5771 if (a === null || typeof a !== "object") a = {}; 5772 if (b === null || typeof b !== "object") b = {}; 5773 5774 for (k in b) { 5775 if (k in a) { 5776 i[k] = interpolate(a[k], b[k]); 5777 } else { 5778 c[k] = b[k]; 5779 } 5780 } 5781 5782 return function(t) { 5783 for (k in i) c[k] = i[k](t); 5784 return c; 5785 }; 5786 } 5787 5788 var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, 5789 reB = new RegExp(reA.source, "g"); 5790 5791 function zero(b) { 5792 return function() { 5793 return b; 5794 }; 5795 } 5796 5797 function one(b) { 5798 return function(t) { 5799 return b(t) + ""; 5800 }; 5801 } 5802 5803 function string(a, b) { 5804 var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b 5805 am, // current match in a 5806 bm, // current match in b 5807 bs, // string preceding current number in b, if any 5808 i = -1, // index in s 5809 s = [], // string constants and placeholders 5810 q = []; // number interpolators 5811 5812 // Coerce inputs to strings. 5813 a = a + "", b = b + ""; 5814 5815 // Interpolate pairs of numbers in a & b. 5816 while ((am = reA.exec(a)) 5817 && (bm = reB.exec(b))) { 5818 if ((bs = bm.index) > bi) { // a string precedes the next number in b 5819 bs = b.slice(bi, bs); 5820 if (s[i]) s[i] += bs; // coalesce with previous string 5821 else s[++i] = bs; 5822 } 5823 if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match 5824 if (s[i]) s[i] += bm; // coalesce with previous string 5825 else s[++i] = bm; 5826 } else { // interpolate non-matching numbers 5827 s[++i] = null; 5828 q.push({i: i, x: interpolateNumber(am, bm)}); 5829 } 5830 bi = reB.lastIndex; 5831 } 5832 5833 // Add remains of b. 5834 if (bi < b.length) { 5835 bs = b.slice(bi); 5836 if (s[i]) s[i] += bs; // coalesce with previous string 5837 else s[++i] = bs; 5838 } 5839 5840 // Special optimization for only a single match. 5841 // Otherwise, interpolate each of the numbers and rejoin the string. 5842 return s.length < 2 ? (q[0] 5843 ? one(q[0].x) 5844 : zero(b)) 5845 : (b = q.length, function(t) { 5846 for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); 5847 return s.join(""); 5848 }); 5849 } 5850 5851 function interpolate(a, b) { 5852 var t = typeof b, c; 5853 return b == null || t === "boolean" ? constant(b) 5854 : (t === "number" ? interpolateNumber 5855 : t === "string" ? ((c = color(b)) ? (b = c, rgb$1) : string) 5856 : b instanceof color ? rgb$1 5857 : b instanceof Date ? date 5858 : isNumberArray(b) ? numberArray 5859 : Array.isArray(b) ? genericArray 5860 : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object 5861 : interpolateNumber)(a, b); 5862 } 5863 5864 function interpolateRound(a, b) { 5865 return a = +a, b = +b, function(t) { 5866 return Math.round(a * (1 - t) + b * t); 5867 }; 5868 } 5869 5870 function constant$1(x) { 5871 return function() { 5872 return x; 5873 }; 5874 } 5875 5876 function number(x) { 5877 return +x; 5878 } 5879 5880 var unit = [0, 1]; 5881 5882 function identity(x) { 5883 return x; 5884 } 5885 5886 function normalize(a, b) { 5887 return (b -= (a = +a)) 5888 ? function(x) { return (x - a) / b; } 5889 : constant$1(isNaN(b) ? NaN : 0.5); 5890 } 5891 5892 function clamper(a, b) { 5893 var t; 5894 if (a > b) t = a, a = b, b = t; 5895 return function(x) { return Math.max(a, Math.min(b, x)); }; 5896 } 5897 5898 // normalize(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1]. 5899 // interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding range value x in [a,b]. 5900 function bimap(domain, range, interpolate) { 5901 var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1]; 5902 if (d1 < d0) d0 = normalize(d1, d0), r0 = interpolate(r1, r0); 5903 else d0 = normalize(d0, d1), r0 = interpolate(r0, r1); 5904 return function(x) { return r0(d0(x)); }; 5905 } 5906 5907 function polymap(domain, range, interpolate) { 5908 var j = Math.min(domain.length, range.length) - 1, 5909 d = new Array(j), 5910 r = new Array(j), 5911 i = -1; 5912 5913 // Reverse descending domains. 5914 if (domain[j] < domain[0]) { 5915 domain = domain.slice().reverse(); 5916 range = range.slice().reverse(); 5917 } 5918 5919 while (++i < j) { 5920 d[i] = normalize(domain[i], domain[i + 1]); 5921 r[i] = interpolate(range[i], range[i + 1]); 5922 } 5923 5924 return function(x) { 5925 var i = bisectRight(domain, x, 1, j) - 1; 5926 return r[i](d[i](x)); 5927 }; 5928 } 5929 5930 function copy(source, target) { 5931 return target 5932 .domain(source.domain()) 5933 .range(source.range()) 5934 .interpolate(source.interpolate()) 5935 .clamp(source.clamp()) 5936 .unknown(source.unknown()); 5937 } 5938 5939 function transformer() { 5940 var domain = unit, 5941 range = unit, 5942 interpolate$1 = interpolate, 5943 transform, 5944 untransform, 5945 unknown, 5946 clamp = identity, 5947 piecewise, 5948 output, 5949 input; 5950 5951 function rescale() { 5952 var n = Math.min(domain.length, range.length); 5953 if (clamp !== identity) clamp = clamper(domain[0], domain[n - 1]); 5954 piecewise = n > 2 ? polymap : bimap; 5955 output = input = null; 5956 return scale; 5957 } 5958 5959 function scale(x) { 5960 return isNaN(x = +x) ? unknown : (output || (output = piecewise(domain.map(transform), range, interpolate$1)))(transform(clamp(x))); 5961 } 5962 5963 scale.invert = function(y) { 5964 return clamp(untransform((input || (input = piecewise(range, domain.map(transform), interpolateNumber)))(y))); 5965 }; 5966 5967 scale.domain = function(_) { 5968 return arguments.length ? (domain = Array.from(_, number), rescale()) : domain.slice(); 5969 }; 5970 5971 scale.range = function(_) { 5972 return arguments.length ? (range = Array.from(_), rescale()) : range.slice(); 5973 }; 5974 5975 scale.rangeRound = function(_) { 5976 return range = Array.from(_), interpolate$1 = interpolateRound, rescale(); 5977 }; 5978 5979 scale.clamp = function(_) { 5980 return arguments.length ? (clamp = _ ? true : identity, rescale()) : clamp !== identity; 5981 }; 5982 5983 scale.interpolate = function(_) { 5984 return arguments.length ? (interpolate$1 = _, rescale()) : interpolate$1; 5985 }; 5986 5987 scale.unknown = function(_) { 5988 return arguments.length ? (unknown = _, scale) : unknown; 5989 }; 5990 5991 return function(t, u) { 5992 transform = t, untransform = u; 5993 return rescale(); 5994 }; 5995 } 5996 5997 function continuous() { 5998 return transformer()(identity, identity); 5999 } 6000 6001 // Computes the decimal coefficient and exponent of the specified number x with 6002 // significant digits p, where x is positive and p is in [1, 21] or undefined. 6003 // For example, formatDecimal(1.23) returns ["123", 0]. 6004 function formatDecimal(x, p) { 6005 if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity 6006 var i, coefficient = x.slice(0, i); 6007 6008 // The string returned by toExponential either has the form \d\.\d+e[-+]\d+ 6009 // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3). 6010 return [ 6011 coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, 6012 +x.slice(i + 1) 6013 ]; 6014 } 6015 6016 function exponent(x) { 6017 return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN; 6018 } 6019 6020 function formatGroup(grouping, thousands) { 6021 return function(value, width) { 6022 var i = value.length, 6023 t = [], 6024 j = 0, 6025 g = grouping[0], 6026 length = 0; 6027 6028 while (i > 0 && g > 0) { 6029 if (length + g + 1 > width) g = Math.max(1, width - length); 6030 t.push(value.substring(i -= g, i + g)); 6031 if ((length += g + 1) > width) break; 6032 g = grouping[j = (j + 1) % grouping.length]; 6033 } 6034 6035 return t.reverse().join(thousands); 6036 }; 6037 } 6038 6039 function formatNumerals(numerals) { 6040 return function(value) { 6041 return value.replace(/[0-9]/g, function(i) { 6042 return numerals[+i]; 6043 }); 6044 }; 6045 } 6046 6047 // [[fill]align][sign][symbol][0][width][,][.precision][~][type] 6048 var re = /^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i; 6049 6050 function formatSpecifier(specifier) { 6051 if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier); 6052 var match; 6053 return new FormatSpecifier({ 6054 fill: match[1], 6055 align: match[2], 6056 sign: match[3], 6057 symbol: match[4], 6058 zero: match[5], 6059 width: match[6], 6060 comma: match[7], 6061 precision: match[8] && match[8].slice(1), 6062 trim: match[9], 6063 type: match[10] 6064 }); 6065 } 6066 6067 formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof 6068 6069 function FormatSpecifier(specifier) { 6070 this.fill = specifier.fill === undefined ? " " : specifier.fill + ""; 6071 this.align = specifier.align === undefined ? ">" : specifier.align + ""; 6072 this.sign = specifier.sign === undefined ? "-" : specifier.sign + ""; 6073 this.symbol = specifier.symbol === undefined ? "" : specifier.symbol + ""; 6074 this.zero = !!specifier.zero; 6075 this.width = specifier.width === undefined ? undefined : +specifier.width; 6076 this.comma = !!specifier.comma; 6077 this.precision = specifier.precision === undefined ? undefined : +specifier.precision; 6078 this.trim = !!specifier.trim; 6079 this.type = specifier.type === undefined ? "" : specifier.type + ""; 6080 } 6081 6082 FormatSpecifier.prototype.toString = function() { 6083 return this.fill 6084 + this.align 6085 + this.sign 6086 + this.symbol 6087 + (this.zero ? "0" : "") 6088 + (this.width === undefined ? "" : Math.max(1, this.width | 0)) 6089 + (this.comma ? "," : "") 6090 + (this.precision === undefined ? "" : "." + Math.max(0, this.precision | 0)) 6091 + (this.trim ? "~" : "") 6092 + this.type; 6093 }; 6094 6095 // Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k. 6096 function formatTrim(s) { 6097 out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) { 6098 switch (s[i]) { 6099 case ".": i0 = i1 = i; break; 6100 case "0": if (i0 === 0) i0 = i; i1 = i; break; 6101 default: if (!+s[i]) break out; if (i0 > 0) i0 = 0; break; 6102 } 6103 } 6104 return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s; 6105 } 6106 6107 var prefixExponent; 6108 6109 function formatPrefixAuto(x, p) { 6110 var d = formatDecimal(x, p); 6111 if (!d) return x + ""; 6112 var coefficient = d[0], 6113 exponent = d[1],
vendor: 10,369 bytes, lines 6114-6385
6114 i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, 6115 n = coefficient.length; 6116 return i === n ? coefficient 6117 : i > n ? coefficient + new Array(i - n + 1).join("0") 6118 : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) 6119 : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y! 6120 } 6121 6122 function formatRounded(x, p) { 6123 var d = formatDecimal(x, p); 6124 if (!d) return x + ""; 6125 var coefficient = d[0], 6126 exponent = d[1]; 6127 return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient 6128 : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) 6129 : coefficient + new Array(exponent - coefficient.length + 2).join("0"); 6130 } 6131 6132 var formatTypes = { 6133 "%": function(x, p) { return (x * 100).toFixed(p); }, 6134 "b": function(x) { return Math.round(x).toString(2); }, 6135 "c": function(x) { return x + ""; }, 6136 "d": function(x) { return Math.round(x).toString(10); }, 6137 "e": function(x, p) { return x.toExponential(p); }, 6138 "f": function(x, p) { return x.toFixed(p); }, 6139 "g": function(x, p) { return x.toPrecision(p); }, 6140 "o": function(x) { return Math.round(x).toString(8); }, 6141 "p": function(x, p) { return formatRounded(x * 100, p); }, 6142 "r": formatRounded, 6143 "s": formatPrefixAuto, 6144 "X": function(x) { return Math.round(x).toString(16).toUpperCase(); }, 6145 "x": function(x) { return Math.round(x).toString(16); } 6146 }; 6147 6148 function identity$1(x) { 6149 return x; 6150 } 6151 6152 var map = Array.prototype.map, 6153 prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"]; 6154 6155 function formatLocale(locale) { 6156 var group = locale.grouping === undefined || locale.thousands === undefined ? identity$1 : formatGroup(map.call(locale.grouping, Number), locale.thousands + ""), 6157 currencyPrefix = locale.currency === undefined ? "" : locale.currency[0] + "", 6158 currencySuffix = locale.currency === undefined ? "" : locale.currency[1] + "", 6159 decimal = locale.decimal === undefined ? "." : locale.decimal + "", 6160 numerals = locale.numerals === undefined ? identity$1 : formatNumerals(map.call(locale.numerals, String)), 6161 percent = locale.percent === undefined ? "%" : locale.percent + "", 6162 minus = locale.minus === undefined ? "-" : locale.minus + "", 6163 nan = locale.nan === undefined ? "NaN" : locale.nan + ""; 6164 6165 function newFormat(specifier) { 6166 specifier = formatSpecifier(specifier); 6167 6168 var fill = specifier.fill, 6169 align = specifier.align, 6170 sign = specifier.sign, 6171 symbol = specifier.symbol, 6172 zero = specifier.zero, 6173 width = specifier.width, 6174 comma = specifier.comma, 6175 precision = specifier.precision, 6176 trim = specifier.trim, 6177 type = specifier.type; 6178 6179 // The "n" type is an alias for ",g". 6180 if (type === "n") comma = true, type = "g"; 6181 6182 // The "" type, and any invalid type, is an alias for ".12~g". 6183 else if (!formatTypes[type]) precision === undefined && (precision = 12), trim = true, type = "g"; 6184 6185 // If zero fill is specified, padding goes after sign and before digits. 6186 if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "="; 6187 6188 // Compute the prefix and suffix. 6189 // For SI-prefix, the suffix is lazily computed. 6190 var prefix = symbol === "$" ? currencyPrefix : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "", 6191 suffix = symbol === "$" ? currencySuffix : /[%p]/.test(type) ? percent : ""; 6192 6193 // What format function should we use? 6194 // Is this an integer type? 6195 // Can this type generate exponential notation? 6196 var formatType = formatTypes[type], 6197 maybeSuffix = /[defgprs%]/.test(type); 6198 6199 // Set the default precision if not specified, 6200 // or clamp the specified precision to the supported range. 6201 // For significant precision, it must be in [1, 21]. 6202 // For fixed precision, it must be in [0, 20]. 6203 precision = precision === undefined ? 6 6204 : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) 6205 : Math.max(0, Math.min(20, precision)); 6206 6207 function format(value) { 6208 var valuePrefix = prefix, 6209 valueSuffix = suffix, 6210 i, n, c; 6211 6212 if (type === "c") { 6213 valueSuffix = formatType(value) + valueSuffix; 6214 value = ""; 6215 } else { 6216 value = +value; 6217 6218 // Determine the sign. -0 is not less than 0, but 1 / -0 is! 6219 var valueNegative = value < 0 || 1 / value < 0; 6220 6221 // Perform the initial formatting. 6222 value = isNaN(value) ? nan : formatType(Math.abs(value), precision); 6223 6224 // Trim insignificant zeros. 6225 if (trim) value = formatTrim(value); 6226 6227 // If a negative value rounds to zero after formatting, and no explicit positive sign is requested, hide the sign. 6228 if (valueNegative && +value === 0 && sign !== "+") valueNegative = false; 6229 6230 // Compute the prefix and suffix. 6231 valuePrefix = (valueNegative ? (sign === "(" ? sign : minus) : sign === "-" || sign === "(" ? "" : sign) + valuePrefix; 6232 valueSuffix = (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign === "(" ? ")" : ""); 6233 6234 // Break the formatted value into the integer âvalueâ part that can be 6235 // grouped, and fractional or exponential âsuffixâ part that is not. 6236 if (maybeSuffix) { 6237 i = -1, n = value.length; 6238 while (++i < n) { 6239 if (c = value.charCodeAt(i), 48 > c || c > 57) { 6240 valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix; 6241 value = value.slice(0, i); 6242 break; 6243 } 6244 } 6245 } 6246 } 6247 6248 // If the fill character is not "0", grouping is applied before padding. 6249 if (comma && !zero) value = group(value, Infinity); 6250 6251 // Compute the padding. 6252 var length = valuePrefix.length + value.length + valueSuffix.length, 6253 padding = length < width ? new Array(width - length + 1).join(fill) : ""; 6254 6255 // If the fill character is "0", grouping is applied after padding. 6256 if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; 6257 6258 // Reconstruct the final output based on the desired alignment. 6259 switch (align) { 6260 case "<": value = valuePrefix + value + valueSuffix + padding; break; 6261 case "=": value = valuePrefix + padding + value + valueSuffix; break; 6262 case "^": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break; 6263 default: value = padding + valuePrefix + value + valueSuffix; break; 6264 } 6265 6266 return numerals(value); 6267 } 6268 6269 format.toString = function() { 6270 return specifier + ""; 6271 }; 6272 6273 return format; 6274 } 6275 6276 function formatPrefix(specifier, value) { 6277 var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)), 6278 e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3, 6279 k = Math.pow(10, -e), 6280 prefix = prefixes[8 + e / 3]; 6281 return function(value) { 6282 return f(k * value) + prefix; 6283 }; 6284 } 6285 6286 return { 6287 format: newFormat, 6288 formatPrefix: formatPrefix 6289 }; 6290 } 6291 6292 var locale; 6293 var format; 6294 var formatPrefix; 6295 6296 defaultLocale({ 6297 decimal: ".", 6298 thousands: ",", 6299 grouping: [3], 6300 currency: ["$", ""], 6301 minus: "-" 6302 }); 6303 6304 function defaultLocale(definition) { 6305 locale = formatLocale(definition); 6306 format = locale.format; 6307 formatPrefix = locale.formatPrefix; 6308 return locale; 6309 } 6310 6311 function precisionFixed(step) { 6312 return Math.max(0, -exponent(Math.abs(step))); 6313 } 6314 6315 function precisionPrefix(step, value) { 6316 return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step))); 6317 } 6318 6319 function precisionRound(step, max) { 6320 step = Math.abs(step), max = Math.abs(max) - step; 6321 return Math.max(0, exponent(max) - exponent(step)) + 1; 6322 } 6323 6324 function tickFormat(start, stop, count, specifier) { 6325 var step = tickStep(start, stop, count), 6326 precision; 6327 specifier = formatSpecifier(specifier == null ? ",f" : specifier); 6328 switch (specifier.type) { 6329 case "s": { 6330 var value = Math.max(Math.abs(start), Math.abs(stop)); 6331 if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision; 6332 return formatPrefix(specifier, value); 6333 } 6334 case "": 6335 case "e": 6336 case "g": 6337 case "p": 6338 case "r": { 6339 if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e"); 6340 break; 6341 } 6342 case "f": 6343 case "%": { 6344 if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2; 6345 break; 6346 } 6347 } 6348 return format(specifier); 6349 } 6350 6351 function linearish(scale) { 6352 var domain = scale.domain; 6353 6354 scale.ticks = function(count) { 6355 var d = domain(); 6356 return ticks(d[0], d[d.length - 1], count == null ? 10 : count); 6357 }; 6358 6359 scale.tickFormat = function(count, specifier) { 6360 var d = domain(); 6361 return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier); 6362 }; 6363 6364 scale.nice = function(count) { 6365 if (count == null) count = 10; 6366 6367 var d = domain(), 6368 i0 = 0, 6369 i1 = d.length - 1, 6370 start = d[i0], 6371 stop = d[i1], 6372 step; 6373 6374 if (stop < start) { 6375 step = start, start = stop, stop = step; 6376 step = i0, i0 = i1, i1 = step; 6377 } 6378 6379 step = tickIncrement(start, stop, count); 6380 6381 if (step > 0) { 6382 start = Math.floor(start / step) * step; 6383 stop = Math.ceil(stop / step) * step; 6384 step = tickIncrement(start, stop, count); 6385 } else if (step < 0) {
6386 start = Math.ceil(start * step) / step; 6387 stop = Math.floor(stop * step) / step; 6388 step = tickIncrement(start, stop, count); 6389 } 6390 6391 if (step > 0) { 6392 d[i0] = Math.floor(start / step) * step; 6393 d[i1] = Math.ceil(stop / step) * step; 6394 domain(d); 6395 } else if (step < 0) { 6396 d[i0] = Math.ceil(start * step) / step; 6397 d[i1] = Math.floor(stop * step) / step; 6398 domain(d); 6399 } 6400 6401 return scale; 6402 }; 6403 6404 return scale; 6405 } 6406 6407 function linear$1() { 6408 var scale = continuous(); 6409 6410 scale.copy = function() { 6411 return copy(scale, linear$1()); 6412 }; 6413 6414 initRange.apply(scale, arguments); 6415 6416 return linearish(scale); 6417 } 6418 6419 var t0$1 = new Date, 6420 t1$1 = new Date; 6421 6422 function newInterval(floori, offseti, count, field) { 6423 6424 function interval(date) { 6425 return floori(date = arguments.length === 0 ? new Date : new Date(+date)), date; 6426 } 6427 6428 interval.floor = function(date) { 6429 return floori(date = new Date(+date)), date; 6430 }; 6431 6432 interval.ceil = function(date) { 6433 return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date; 6434 }; 6435 6436 interval.round = function(date) { 6437 var d0 = interval(date), 6438 d1 = interval.ceil(date); 6439 return date - d0 < d1 - date ? d0 : d1; 6440 }; 6441 6442 interval.offset = function(date, step) { 6443 return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date; 6444 }; 6445 6446 interval.range = function(start, stop, step) { 6447 var range = [], previous; 6448 start = interval.ceil(start); 6449 step = step == null ? 1 : Math.floor(step); 6450 if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date 6451 do range.push(previous = new Date(+start)), offseti(start, step), floori(start); 6452 while (previous < start && start < stop); 6453 return range; 6454 }; 6455 6456 interval.filter = function(test) { 6457 return newInterval(function(date) { 6458 if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1); 6459 }, function(date, step) { 6460 if (date >= date) { 6461 if (step < 0) while (++step <= 0) { 6462 while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty 6463 } else while (--step >= 0) { 6464 while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty 6465 } 6466 } 6467 }); 6468 }; 6469 6470 if (count) { 6471 interval.count = function(start, end) { 6472 t0$1.setTime(+start), t1$1.setTime(+end); 6473 floori(t0$1), floori(t1$1); 6474 return Math.floor(count(t0$1, t1$1)); 6475 }; 6476 6477 interval.every = function(step) { 6478 step = Math.floor(step); 6479 return !isFinite(step) || !(step > 0) ? null 6480 : !(step > 1) ? interval 6481 : interval.filter(field 6482 ? function(d) { return field(d) % step === 0; } 6483 : function(d) { return interval.count(0, d) % step === 0; }); 6484 }; 6485 } 6486 6487 return interval; 6488 } 6489 6490 var millisecond = newInterval(function() { 6491 // noop 6492 }, function(date, step) { 6493 date.setTime(+date + step); 6494 }, function(start, end) { 6495 return end - start; 6496 }); 6497 6498 // An optimized implementation for this simple case. 6499 millisecond.every = function(k) { 6500 k = Math.floor(k); 6501 if (!isFinite(k) || !(k > 0)) return null; 6502 if (!(k > 1)) return millisecond; 6503 return newInterval(function(date) { 6504 date.setTime(Math.floor(date / k) * k); 6505 }, function(date, step) { 6506 date.setTime(+date + step * k); 6507 }, function(start, end) { 6508 return (end - start) / k; 6509 }); 6510 }; 6511 6512 var durationSecond = 1e3; 6513 var durationMinute = 6e4; 6514 var durationHour = 36e5; 6515 var durationDay = 864e5; 6516 var durationWeek = 6048e5; 6517 6518 var second = newInterval(function(date) { 6519 date.setTime(date - date.getMilliseconds()); 6520 }, function(date, step) { 6521 date.setTime(+date + step * durationSecond); 6522 }, function(start, end) { 6523 return (end - start) / durationSecond; 6524 }, function(date) { 6525 return date.getUTCSeconds(); 6526 }); 6527 6528 var minute = newInterval(function(date) { 6529 date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond); 6530 }, function(date, step) { 6531 date.setTime(+date + step * durationMinute); 6532 }, function(start, end) { 6533 return (end - start) / durationMinute; 6534 }, function(date) { 6535 return date.getMinutes(); 6536 }); 6537 6538 var hour = newInterval(function(date) { 6539 date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond - date.getMinutes() * durationMinute); 6540 }, function(date, step) { 6541 date.setTime(+date + step * durationHour); 6542 }, function(start, end) { 6543 return (end - start) / durationHour; 6544 }, function(date) { 6545 return date.getHours(); 6546 }); 6547 6548 var day = newInterval(function(date) { 6549 date.setHours(0, 0, 0, 0); 6550 }, function(date, step) { 6551 date.setDate(date.getDate() + step); 6552 }, function(start, end) { 6553 return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay; 6554 }, function(date) { 6555 return date.getDate() - 1; 6556 }); 6557 6558 function weekday(i) { 6559 return newInterval(function(date) { 6560 date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7); 6561 date.setHours(0, 0, 0, 0); 6562 }, function(date, step) { 6563 date.setDate(date.getDate() + step * 7); 6564 }, function(start, end) { 6565 return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek; 6566 }); 6567 } 6568 6569 var sunday = weekday(0); 6570 var monday = weekday(1); 6571 var tuesday = weekday(2); 6572 var wednesday = weekday(3); 6573 var thursday = weekday(4); 6574 var friday = weekday(5); 6575 var saturday = weekday(6); 6576
vendor: 5,511 bytes, lines 6577-6749
6577 var month = newInterval(function(date) { 6578 date.setDate(1); 6579 date.setHours(0, 0, 0, 0); 6580 }, function(date, step) { 6581 date.setMonth(date.getMonth() + step); 6582 }, function(start, end) { 6583 return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12; 6584 }, function(date) { 6585 return date.getMonth(); 6586 }); 6587 6588 var year = newInterval(function(date) { 6589 date.setMonth(0, 1); 6590 date.setHours(0, 0, 0, 0); 6591 }, function(date, step) { 6592 date.setFullYear(date.getFullYear() + step); 6593 }, function(start, end) { 6594 return end.getFullYear() - start.getFullYear(); 6595 }, function(date) { 6596 return date.getFullYear(); 6597 }); 6598 6599 // An optimized implementation for this simple case. 6600 year.every = function(k) { 6601 return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) { 6602 date.setFullYear(Math.floor(date.getFullYear() / k) * k); 6603 date.setMonth(0, 1); 6604 date.setHours(0, 0, 0, 0); 6605 }, function(date, step) { 6606 date.setFullYear(date.getFullYear() + step * k); 6607 }); 6608 }; 6609 6610 var utcMinute = newInterval(function(date) { 6611 date.setUTCSeconds(0, 0); 6612 }, function(date, step) { 6613 date.setTime(+date + step * durationMinute); 6614 }, function(start, end) { 6615 return (end - start) / durationMinute; 6616 }, function(date) { 6617 return date.getUTCMinutes(); 6618 }); 6619 6620 var utcHour = newInterval(function(date) { 6621 date.setUTCMinutes(0, 0, 0); 6622 }, function(date, step) { 6623 date.setTime(+date + step * durationHour); 6624 }, function(start, end) { 6625 return (end - start) / durationHour; 6626 }, function(date) { 6627 return date.getUTCHours(); 6628 }); 6629 6630 var utcDay = newInterval(function(date) { 6631 date.setUTCHours(0, 0, 0, 0); 6632 }, function(date, step) { 6633 date.setUTCDate(date.getUTCDate() + step); 6634 }, function(start, end) { 6635 return (end - start) / durationDay; 6636 }, function(date) { 6637 return date.getUTCDate() - 1; 6638 }); 6639 6640 function utcWeekday(i) { 6641 return newInterval(function(date) { 6642 date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7); 6643 date.setUTCHours(0, 0, 0, 0); 6644 }, function(date, step) { 6645 date.setUTCDate(date.getUTCDate() + step * 7); 6646 }, function(start, end) { 6647 return (end - start) / durationWeek; 6648 }); 6649 } 6650 6651 var utcSunday = utcWeekday(0); 6652 var utcMonday = utcWeekday(1); 6653 var utcTuesday = utcWeekday(2); 6654 var utcWednesday = utcWeekday(3); 6655 var utcThursday = utcWeekday(4); 6656 var utcFriday = utcWeekday(5); 6657 var utcSaturday = utcWeekday(6); 6658 6659 var utcMonth = newInterval(function(date) { 6660 date.setUTCDate(1); 6661 date.setUTCHours(0, 0, 0, 0); 6662 }, function(date, step) { 6663 date.setUTCMonth(date.getUTCMonth() + step); 6664 }, function(start, end) { 6665 return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12; 6666 }, function(date) { 6667 return date.getUTCMonth(); 6668 }); 6669 6670 var utcYear = newInterval(function(date) { 6671 date.setUTCMonth(0, 1); 6672 date.setUTCHours(0, 0, 0, 0); 6673 }, function(date, step) { 6674 date.setUTCFullYear(date.getUTCFullYear() + step); 6675 }, function(start, end) { 6676 return end.getUTCFullYear() - start.getUTCFullYear(); 6677 }, function(date) { 6678 return date.getUTCFullYear(); 6679 }); 6680 6681 // An optimized implementation for this simple case. 6682 utcYear.every = function(k) { 6683 return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) { 6684 date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k); 6685 date.setUTCMonth(0, 1); 6686 date.setUTCHours(0, 0, 0, 0); 6687 }, function(date, step) { 6688 date.setUTCFullYear(date.getUTCFullYear() + step * k); 6689 }); 6690 }; 6691 6692 function localDate(d) { 6693 if (0 <= d.y && d.y < 100) { 6694 var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L); 6695 date.setFullYear(d.y); 6696 return date; 6697 } 6698 return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L); 6699 } 6700 6701 function utcDate(d) { 6702 if (0 <= d.y && d.y < 100) { 6703 var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L)); 6704 date.setUTCFullYear(d.y); 6705 return date; 6706 } 6707 return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L)); 6708 } 6709 6710 function newDate(y, m, d) { 6711 return {y: y, m: m, d: d, H: 0, M: 0, S: 0, L: 0}; 6712 } 6713 6714 function formatLocale$1(locale) { 6715 var locale_dateTime = locale.dateTime, 6716 locale_date = locale.date, 6717 locale_time = locale.time, 6718 locale_periods = locale.periods, 6719 locale_weekdays = locale.days, 6720 locale_shortWeekdays = locale.shortDays, 6721 locale_months = locale.months, 6722 locale_shortMonths = locale.shortMonths; 6723 6724 var periodRe = formatRe(locale_periods), 6725 periodLookup = formatLookup(locale_periods), 6726 weekdayRe = formatRe(locale_weekdays), 6727 weekdayLookup = formatLookup(locale_weekdays), 6728 shortWeekdayRe = formatRe(locale_shortWeekdays), 6729 shortWeekdayLookup = formatLookup(locale_shortWeekdays), 6730 monthRe = formatRe(locale_months), 6731 monthLookup = formatLookup(locale_months), 6732 shortMonthRe = formatRe(locale_shortMonths), 6733 shortMonthLookup = formatLookup(locale_shortMonths); 6734 6735 var formats = { 6736 "a": formatShortWeekday, 6737 "A": formatWeekday, 6738 "b": formatShortMonth, 6739 "B": formatMonth, 6740 "c": null, 6741 "d": formatDayOfMonth, 6742 "e": formatDayOfMonth, 6743 "f": formatMicroseconds, 6744 "H": formatHour24, 6745 "I": formatHour12, 6746 "j": formatDayOfYear, 6747 "L": formatMilliseconds, 6748 "m": formatMonthNumber, 6749 "M": formatMinutes,
vendor: 6,581 bytes, lines 6750-6955
6750 "p": formatPeriod, 6751 "q": formatQuarter, 6752 "Q": formatUnixTimestamp, 6753 "s": formatUnixTimestampSeconds, 6754 "S": formatSeconds, 6755 "u": formatWeekdayNumberMonday, 6756 "U": formatWeekNumberSunday, 6757 "V": formatWeekNumberISO, 6758 "w": formatWeekdayNumberSunday, 6759 "W": formatWeekNumberMonday, 6760 "x": null, 6761 "X": null, 6762 "y": formatYear, 6763 "Y": formatFullYear, 6764 "Z": formatZone, 6765 "%": formatLiteralPercent 6766 }; 6767 6768 var utcFormats = { 6769 "a": formatUTCShortWeekday, 6770 "A": formatUTCWeekday, 6771 "b": formatUTCShortMonth, 6772 "B": formatUTCMonth, 6773 "c": null, 6774 "d": formatUTCDayOfMonth, 6775 "e": formatUTCDayOfMonth, 6776 "f": formatUTCMicroseconds, 6777 "H": formatUTCHour24, 6778 "I": formatUTCHour12, 6779 "j": formatUTCDayOfYear, 6780 "L": formatUTCMilliseconds, 6781 "m": formatUTCMonthNumber, 6782 "M": formatUTCMinutes, 6783 "p": formatUTCPeriod, 6784 "q": formatUTCQuarter, 6785 "Q": formatUnixTimestamp, 6786 "s": formatUnixTimestampSeconds, 6787 "S": formatUTCSeconds, 6788 "u": formatUTCWeekdayNumberMonday, 6789 "U": formatUTCWeekNumberSunday, 6790 "V": formatUTCWeekNumberISO, 6791 "w": formatUTCWeekdayNumberSunday, 6792 "W": formatUTCWeekNumberMonday, 6793 "x": null, 6794 "X": null, 6795 "y": formatUTCYear, 6796 "Y": formatUTCFullYear, 6797 "Z": formatUTCZone, 6798 "%": formatLiteralPercent 6799 }; 6800 6801 var parses = { 6802 "a": parseShortWeekday, 6803 "A": parseWeekday, 6804 "b": parseShortMonth, 6805 "B": parseMonth, 6806 "c": parseLocaleDateTime, 6807 "d": parseDayOfMonth, 6808 "e": parseDayOfMonth, 6809 "f": parseMicroseconds, 6810 "H": parseHour24, 6811 "I": parseHour24, 6812 "j": parseDayOfYear, 6813 "L": parseMilliseconds, 6814 "m": parseMonthNumber, 6815 "M": parseMinutes, 6816 "p": parsePeriod, 6817 "q": parseQuarter, 6818 "Q": parseUnixTimestamp, 6819 "s": parseUnixTimestampSeconds, 6820 "S": parseSeconds, 6821 "u": parseWeekdayNumberMonday, 6822 "U": parseWeekNumberSunday, 6823 "V": parseWeekNumberISO, 6824 "w": parseWeekdayNumberSunday, 6825 "W": parseWeekNumberMonday, 6826 "x": parseLocaleDate, 6827 "X": parseLocaleTime, 6828 "y": parseYear, 6829 "Y": parseFullYear, 6830 "Z": parseZone, 6831 "%": parseLiteralPercent 6832 }; 6833 6834 // These recursive directive definitions must be deferred. 6835 formats.x = newFormat(locale_date, formats); 6836 formats.X = newFormat(locale_time, formats); 6837 formats.c = newFormat(locale_dateTime, formats); 6838 utcFormats.x = newFormat(locale_date, utcFormats); 6839 utcFormats.X = newFormat(locale_time, utcFormats); 6840 utcFormats.c = newFormat(locale_dateTime, utcFormats); 6841 6842 function newFormat(specifier, formats) { 6843 return function(date) { 6844 var string = [], 6845 i = -1, 6846 j = 0, 6847 n = specifier.length, 6848 c, 6849 pad, 6850 format; 6851 6852 if (!(date instanceof Date)) date = new Date(+date); 6853 6854 while (++i < n) { 6855 if (specifier.charCodeAt(i) === 37) { 6856 string.push(specifier.slice(j, i)); 6857 if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i); 6858 else pad = c === "e" ? " " : "0"; 6859 if (format = formats[c]) c = format(date, pad); 6860 string.push(c); 6861 j = i + 1; 6862 } 6863 } 6864 6865 string.push(specifier.slice(j, i)); 6866 return string.join(""); 6867 }; 6868 } 6869 6870 function newParse(specifier, Z) { 6871 return function(string) { 6872 var d = newDate(1900, undefined, 1), 6873 i = parseSpecifier(d, specifier, string += "", 0), 6874 week, day$1; 6875 if (i != string.length) return null; 6876 6877 // If a UNIX timestamp is specified, return it. 6878 if ("Q" in d) return new Date(d.Q); 6879 if ("s" in d) return new Date(d.s * 1000 + ("L" in d ? d.L : 0)); 6880 6881 // If this is utcParse, never use the local timezone. 6882 if (Z && !("Z" in d)) d.Z = 0; 6883 6884 // The am-pm flag is 0 for AM, and 1 for PM. 6885 if ("p" in d) d.H = d.H % 12 + d.p * 12; 6886 6887 // If the month was not specified, inherit from the quarter. 6888 if (d.m === undefined) d.m = "q" in d ? d.q : 0; 6889 6890 // Convert day-of-week and week-of-year to day-of-year. 6891 if ("V" in d) { 6892 if (d.V < 1 || d.V > 53) return null; 6893 if (!("w" in d)) d.w = 1; 6894 if ("Z" in d) { 6895 week = utcDate(newDate(d.y, 0, 1)), day$1 = week.getUTCDay(); 6896 week = day$1 > 4 || day$1 === 0 ? utcMonday.ceil(week) : utcMonday(week); 6897 week = utcDay.offset(week, (d.V - 1) * 7); 6898 d.y = week.getUTCFullYear(); 6899 d.m = week.getUTCMonth(); 6900 d.d = week.getUTCDate() + (d.w + 6) % 7; 6901 } else { 6902 week = localDate(newDate(d.y, 0, 1)), day$1 = week.getDay(); 6903 week = day$1 > 4 || day$1 === 0 ? monday.ceil(week) : monday(week); 6904 week = day.offset(week, (d.V - 1) * 7); 6905 d.y = week.getFullYear(); 6906 d.m = week.getMonth(); 6907 d.d = week.getDate() + (d.w + 6) % 7; 6908 } 6909 } else if ("W" in d || "U" in d) { 6910 if (!("w" in d)) d.w = "u" in d ? d.u % 7 : "W" in d ? 1 : 0; 6911 day$1 = "Z" in d ? utcDate(newDate(d.y, 0, 1)).getUTCDay() : localDate(newDate(d.y, 0, 1)).getDay(); 6912 d.m = 0; 6913 d.d = "W" in d ? (d.w + 6) % 7 + d.W * 7 - (day$1 + 5) % 7 : d.w + d.U * 7 - (day$1 + 6) % 7; 6914 } 6915 6916 // If a time zone is specified, all fields are interpreted as UTC and then 6917 // offset according to the specified time zone. 6918 if ("Z" in d) { 6919 d.H += d.Z / 100 | 0; 6920 d.M += d.Z % 100; 6921 return utcDate(d); 6922 } 6923 6924 // Otherwise, all fields are in local time. 6925 return localDate(d); 6926 }; 6927 } 6928 6929 function parseSpecifier(d, specifier, string, j) { 6930 var i = 0, 6931 n = specifier.length, 6932 m = string.length, 6933 c, 6934 parse; 6935 6936 while (i < n) { 6937 if (j >= m) return -1; 6938 c = specifier.charCodeAt(i++); 6939 if (c === 37) { 6940 c = specifier.charAt(i++); 6941 parse = parses[c in pads ? specifier.charAt(i++) : c]; 6942 if (!parse || ((j = parse(d, string, j)) < 0)) return -1; 6943 } else if (c != string.charCodeAt(j++)) { 6944 return -1; 6945 } 6946 } 6947 6948 return j; 6949 } 6950 6951 function parsePeriod(d, string, i) { 6952 var n = periodRe.exec(string.slice(i)); 6953 return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1; 6954 } 6955
vendor: 3,735 bytes, lines 6956-7090
6956 function parseShortWeekday(d, string, i) { 6957 var n = shortWeekdayRe.exec(string.slice(i)); 6958 return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; 6959 } 6960 6961 function parseWeekday(d, string, i) { 6962 var n = weekdayRe.exec(string.slice(i)); 6963 return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; 6964 } 6965 6966 function parseShortMonth(d, string, i) { 6967 var n = shortMonthRe.exec(string.slice(i)); 6968 return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1; 6969 } 6970 6971 function parseMonth(d, string, i) { 6972 var n = monthRe.exec(string.slice(i)); 6973 return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1; 6974 } 6975 6976 function parseLocaleDateTime(d, string, i) { 6977 return parseSpecifier(d, locale_dateTime, string, i); 6978 } 6979 6980 function parseLocaleDate(d, string, i) { 6981 return parseSpecifier(d, locale_date, string, i); 6982 } 6983 6984 function parseLocaleTime(d, string, i) { 6985 return parseSpecifier(d, locale_time, string, i); 6986 } 6987 6988 function formatShortWeekday(d) { 6989 return locale_shortWeekdays[d.getDay()]; 6990 } 6991 6992 function formatWeekday(d) { 6993 return locale_weekdays[d.getDay()]; 6994 } 6995 6996 function formatShortMonth(d) { 6997 return locale_shortMonths[d.getMonth()]; 6998 } 6999 7000 function formatMonth(d) { 7001 return locale_months[d.getMonth()]; 7002 } 7003 7004 function formatPeriod(d) { 7005 return locale_periods[+(d.getHours() >= 12)]; 7006 } 7007 7008 function formatQuarter(d) { 7009 return 1 + ~~(d.getMonth() / 3); 7010 } 7011 7012 function formatUTCShortWeekday(d) { 7013 return locale_shortWeekdays[d.getUTCDay()]; 7014 } 7015 7016 function formatUTCWeekday(d) { 7017 return locale_weekdays[d.getUTCDay()]; 7018 } 7019 7020 function formatUTCShortMonth(d) { 7021 return locale_shortMonths[d.getUTCMonth()]; 7022 } 7023 7024 function formatUTCMonth(d) { 7025 return locale_months[d.getUTCMonth()]; 7026 } 7027 7028 function formatUTCPeriod(d) { 7029 return locale_periods[+(d.getUTCHours() >= 12)]; 7030 } 7031 7032 function formatUTCQuarter(d) { 7033 return 1 + ~~(d.getUTCMonth() / 3); 7034 } 7035 7036 return { 7037 format: function(specifier) { 7038 var f = newFormat(specifier += "", formats); 7039 f.toString = function() { return specifier; }; 7040 return f; 7041 }, 7042 parse: function(specifier) { 7043 var p = newParse(specifier += "", false); 7044 p.toString = function() { return specifier; }; 7045 return p; 7046 }, 7047 utcFormat: function(specifier) { 7048 var f = newFormat(specifier += "", utcFormats); 7049 f.toString = function() { return specifier; }; 7050 return f; 7051 }, 7052 utcParse: function(specifier) { 7053 var p = newParse(specifier += "", true); 7054 p.toString = function() { return specifier; }; 7055 return p; 7056 } 7057 }; 7058 } 7059 7060 var pads = {"-": "", "_": " ", "0": "0"}, 7061 numberRe = /^\s*\d+/, // note: ignores next directive 7062 percentRe = /^%/, 7063 requoteRe = /[\\^$*+?|[\]().{}]/g; 7064 7065 function pad(value, fill, width) { 7066 var sign = value < 0 ? "-" : "", 7067 string = (sign ? -value : value) + "", 7068 length = string.length; 7069 return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); 7070 } 7071 7072 function requote(s) { 7073 return s.replace(requoteRe, "\\$&"); 7074 } 7075 7076 function formatRe(names) { 7077 return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i"); 7078 } 7079 7080 function formatLookup(names) { 7081 var map = {}, i = -1, n = names.length; 7082 while (++i < n) map[names[i].toLowerCase()] = i; 7083 return map; 7084 } 7085 7086 function parseWeekdayNumberSunday(d, string, i) { 7087 var n = numberRe.exec(string.slice(i, i + 1)); 7088 return n ? (d.w = +n[0], i + n[0].length) : -1; 7089 } 7090
vendor: 4,293 bytes, lines 7091-7244
7091 function parseWeekdayNumberMonday(d, string, i) { 7092 var n = numberRe.exec(string.slice(i, i + 1)); 7093 return n ? (d.u = +n[0], i + n[0].length) : -1; 7094 } 7095 7096 function parseWeekNumberSunday(d, string, i) { 7097 var n = numberRe.exec(string.slice(i, i + 2)); 7098 return n ? (d.U = +n[0], i + n[0].length) : -1; 7099 } 7100 7101 function parseWeekNumberISO(d, string, i) { 7102 var n = numberRe.exec(string.slice(i, i + 2)); 7103 return n ? (d.V = +n[0], i + n[0].length) : -1; 7104 } 7105 7106 function parseWeekNumberMonday(d, string, i) { 7107 var n = numberRe.exec(string.slice(i, i + 2)); 7108 return n ? (d.W = +n[0], i + n[0].length) : -1; 7109 } 7110 7111 function parseFullYear(d, string, i) { 7112 var n = numberRe.exec(string.slice(i, i + 4)); 7113 return n ? (d.y = +n[0], i + n[0].length) : -1; 7114 } 7115 7116 function parseYear(d, string, i) { 7117 var n = numberRe.exec(string.slice(i, i + 2)); 7118 return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1; 7119 } 7120 7121 function parseZone(d, string, i) { 7122 var n = /^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(string.slice(i, i + 6)); 7123 return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1; 7124 } 7125 7126 function parseQuarter(d, string, i) { 7127 var n = numberRe.exec(string.slice(i, i + 1)); 7128 return n ? (d.q = n[0] * 3 - 3, i + n[0].length) : -1; 7129 } 7130 7131 function parseMonthNumber(d, string, i) { 7132 var n = numberRe.exec(string.slice(i, i + 2)); 7133 return n ? (d.m = n[0] - 1, i + n[0].length) : -1; 7134 } 7135 7136 function parseDayOfMonth(d, string, i) { 7137 var n = numberRe.exec(string.slice(i, i + 2)); 7138 return n ? (d.d = +n[0], i + n[0].length) : -1; 7139 } 7140 7141 function parseDayOfYear(d, string, i) { 7142 var n = numberRe.exec(string.slice(i, i + 3)); 7143 return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1; 7144 } 7145 7146 function parseHour24(d, string, i) { 7147 var n = numberRe.exec(string.slice(i, i + 2)); 7148 return n ? (d.H = +n[0], i + n[0].length) : -1; 7149 } 7150 7151 function parseMinutes(d, string, i) { 7152 var n = numberRe.exec(string.slice(i, i + 2)); 7153 return n ? (d.M = +n[0], i + n[0].length) : -1; 7154 } 7155 7156 function parseSeconds(d, string, i) { 7157 var n = numberRe.exec(string.slice(i, i + 2)); 7158 return n ? (d.S = +n[0], i + n[0].length) : -1; 7159 } 7160 7161 function parseMilliseconds(d, string, i) { 7162 var n = numberRe.exec(string.slice(i, i + 3)); 7163 return n ? (d.L = +n[0], i + n[0].length) : -1; 7164 } 7165 7166 function parseMicroseconds(d, string, i) { 7167 var n = numberRe.exec(string.slice(i, i + 6)); 7168 return n ? (d.L = Math.floor(n[0] / 1000), i + n[0].length) : -1; 7169 } 7170 7171 function parseLiteralPercent(d, string, i) { 7172 var n = percentRe.exec(string.slice(i, i + 1)); 7173 return n ? i + n[0].length : -1; 7174 } 7175 7176 function parseUnixTimestamp(d, string, i) { 7177 var n = numberRe.exec(string.slice(i)); 7178 return n ? (d.Q = +n[0], i + n[0].length) : -1; 7179 } 7180 7181 function parseUnixTimestampSeconds(d, string, i) { 7182 var n = numberRe.exec(string.slice(i)); 7183 return n ? (d.s = +n[0], i + n[0].length) : -1; 7184 } 7185 7186 function formatDayOfMonth(d, p) { 7187 return pad(d.getDate(), p, 2); 7188 } 7189 7190 function formatHour24(d, p) { 7191 return pad(d.getHours(), p, 2); 7192 } 7193 7194 function formatHour12(d, p) { 7195 return pad(d.getHours() % 12 || 12, p, 2); 7196 } 7197 7198 function formatDayOfYear(d, p) { 7199 return pad(1 + day.count(year(d), d), p, 3); 7200 } 7201 7202 function formatMilliseconds(d, p) { 7203 return pad(d.getMilliseconds(), p, 3); 7204 } 7205 7206 function formatMicroseconds(d, p) { 7207 return formatMilliseconds(d, p) + "000"; 7208 } 7209 7210 function formatMonthNumber(d, p) { 7211 return pad(d.getMonth() + 1, p, 2); 7212 } 7213 7214 function formatMinutes(d, p) { 7215 return pad(d.getMinutes(), p, 2); 7216 } 7217 7218 function formatSeconds(d, p) { 7219 return pad(d.getSeconds(), p, 2); 7220 } 7221 7222 function formatWeekdayNumberMonday(d) { 7223 var day = d.getDay(); 7224 return day === 0 ? 7 : day; 7225 } 7226 7227 function formatWeekNumberSunday(d, p) { 7228 return pad(sunday.count(year(d) - 1, d), p, 2); 7229 } 7230 7231 function formatWeekNumberISO(d, p) { 7232 var day = d.getDay(); 7233 d = (day >= 4 || day === 0) ? thursday(d) : thursday.ceil(d); 7234 return pad(thursday.count(year(d), d) + (year(d).getDay() === 4), p, 2); 7235 } 7236 7237 function formatWeekdayNumberSunday(d) { 7238 return d.getDay(); 7239 } 7240 7241 function formatWeekNumberMonday(d, p) { 7242 return pad(monday.count(year(d) - 1, d), p, 2); 7243 } 7244
vendor: 8,202 bytes, lines 7245-7525
7245 function formatYear(d, p) { 7246 return pad(d.getFullYear() % 100, p, 2); 7247 } 7248 7249 function formatFullYear(d, p) { 7250 return pad(d.getFullYear() % 10000, p, 4); 7251 } 7252 7253 function formatZone(d) { 7254 var z = d.getTimezoneOffset(); 7255 return (z > 0 ? "-" : (z *= -1, "+")) 7256 + pad(z / 60 | 0, "0", 2) 7257 + pad(z % 60, "0", 2); 7258 } 7259 7260 function formatUTCDayOfMonth(d, p) { 7261 return pad(d.getUTCDate(), p, 2); 7262 } 7263 7264 function formatUTCHour24(d, p) { 7265 return pad(d.getUTCHours(), p, 2); 7266 } 7267 7268 function formatUTCHour12(d, p) { 7269 return pad(d.getUTCHours() % 12 || 12, p, 2); 7270 } 7271 7272 function formatUTCDayOfYear(d, p) { 7273 return pad(1 + utcDay.count(utcYear(d), d), p, 3); 7274 } 7275 7276 function formatUTCMilliseconds(d, p) { 7277 return pad(d.getUTCMilliseconds(), p, 3); 7278 } 7279 7280 function formatUTCMicroseconds(d, p) { 7281 return formatUTCMilliseconds(d, p) + "000"; 7282 } 7283 7284 function formatUTCMonthNumber(d, p) { 7285 return pad(d.getUTCMonth() + 1, p, 2); 7286 } 7287 7288 function formatUTCMinutes(d, p) { 7289 return pad(d.getUTCMinutes(), p, 2); 7290 } 7291 7292 function formatUTCSeconds(d, p) { 7293 return pad(d.getUTCSeconds(), p, 2); 7294 } 7295 7296 function formatUTCWeekdayNumberMonday(d) { 7297 var dow = d.getUTCDay(); 7298 return dow === 0 ? 7 : dow; 7299 } 7300 7301 function formatUTCWeekNumberSunday(d, p) { 7302 return pad(utcSunday.count(utcYear(d) - 1, d), p, 2); 7303 } 7304 7305 function formatUTCWeekNumberISO(d, p) { 7306 var day = d.getUTCDay(); 7307 d = (day >= 4 || day === 0) ? utcThursday(d) : utcThursday.ceil(d); 7308 return pad(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() === 4), p, 2); 7309 } 7310 7311 function formatUTCWeekdayNumberSunday(d) { 7312 return d.getUTCDay(); 7313 } 7314 7315 function formatUTCWeekNumberMonday(d, p) { 7316 return pad(utcMonday.count(utcYear(d) - 1, d), p, 2); 7317 } 7318 7319 function formatUTCYear(d, p) { 7320 return pad(d.getUTCFullYear() % 100, p, 2); 7321 } 7322 7323 function formatUTCFullYear(d, p) { 7324 return pad(d.getUTCFullYear() % 10000, p, 4); 7325 } 7326 7327 function formatUTCZone() { 7328 return "+0000"; 7329 } 7330 7331 function formatLiteralPercent() { 7332 return "%"; 7333 } 7334 7335 function formatUnixTimestamp(d) { 7336 return +d; 7337 } 7338 7339 function formatUnixTimestampSeconds(d) { 7340 return Math.floor(+d / 1000); 7341 } 7342 7343 var locale$1; 7344 var timeFormat; 7345 var timeParse; 7346 var utcFormat; 7347 var utcParse; 7348 7349 defaultLocale$1({ 7350 dateTime: "%x, %X", 7351 date: "%-m/%-d/%Y", 7352 time: "%-I:%M:%S %p", 7353 periods: ["AM", "PM"], 7354 days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], 7355 shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], 7356 months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], 7357 shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] 7358 }); 7359 7360 function defaultLocale$1(definition) { 7361 locale$1 = formatLocale$1(definition); 7362 timeFormat = locale$1.format; 7363 timeParse = locale$1.parse; 7364 utcFormat = locale$1.utcFormat; 7365 utcParse = locale$1.utcParse; 7366 return locale$1; 7367 } 7368 7369 var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ"; 7370 7371 function formatIsoNative(date) { 7372 return date.toISOString(); 7373 } 7374 7375 var formatIso = Date.prototype.toISOString 7376 ? formatIsoNative 7377 : utcFormat(isoSpecifier); 7378 7379 function parseIsoNative(string) { 7380 var date = new Date(string); 7381 return isNaN(date) ? null : date; 7382 } 7383 7384 var parseIso = +new Date("2000-01-01T00:00:00.000Z") 7385 ? parseIsoNative 7386 : utcParse(isoSpecifier); 7387 7388 var noop = {value: function() {}}; 7389 7390 function dispatch() { 7391 for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) { 7392 if (!(t = arguments[i] + "") || (t in _) || /[\s.]/.test(t)) throw new Error("illegal type: " + t); 7393 _[t] = []; 7394 } 7395 return new Dispatch(_); 7396 } 7397 7398 function Dispatch(_) { 7399 this._ = _; 7400 } 7401 7402 function parseTypenames(typenames, types) { 7403 return typenames.trim().split(/^|\s+/).map(function(t) { 7404 var name = "", i = t.indexOf("."); 7405 if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); 7406 if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t); 7407 return {type: t, name: name}; 7408 }); 7409 } 7410 7411 Dispatch.prototype = dispatch.prototype = { 7412 constructor: Dispatch, 7413 on: function(typename, callback) { 7414 var _ = this._, 7415 T = parseTypenames(typename + "", _), 7416 t, 7417 i = -1, 7418 n = T.length; 7419 7420 // If no callback was specified, return the callback of the given type and name. 7421 if (arguments.length < 2) { 7422 while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t; 7423 return; 7424 } 7425 7426 // If a type was specified, set the callback for the given type and name. 7427 // Otherwise, if a null callback was specified, remove callbacks of the given name. 7428 if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback); 7429 while (++i < n) { 7430 if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback); 7431 else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null); 7432 } 7433 7434 return this; 7435 }, 7436 copy: function() { 7437 var copy = {}, _ = this._; 7438 for (var t in _) copy[t] = _[t].slice(); 7439 return new Dispatch(copy); 7440 }, 7441 call: function(type, that) { 7442 if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2]; 7443 if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); 7444 for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); 7445 }, 7446 apply: function(type, that, args) { 7447 if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); 7448 for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); 7449 } 7450 }; 7451 7452 function get(type, name) { 7453 for (var i = 0, n = type.length, c; i < n; ++i) { 7454 if ((c = type[i]).name === name) { 7455 return c.value; 7456 } 7457 } 7458 } 7459 7460 function set(type, name, callback) { 7461 for (var i = 0, n = type.length; i < n; ++i) { 7462 if (type[i].name === name) { 7463 type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1)); 7464 break; 7465 } 7466 } 7467 if (callback != null) type.push({name: name, value: callback}); 7468 return type; 7469 } 7470 7471 var xhtml = "http://www.w3.org/1999/xhtml"; 7472 7473 var namespaces = { 7474 svg: "http://www.w3.org/2000/svg", 7475 xhtml: xhtml, 7476 xlink: "http://www.w3.org/1999/xlink", 7477 xml: "http://www.w3.org/XML/1998/namespace", 7478 xmlns: "http://www.w3.org/2000/xmlns/" 7479 }; 7480 7481 function namespace(name) { 7482 var prefix = name += "", i = prefix.indexOf(":"); 7483 if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1); 7484 return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name; 7485 } 7486 7487 function creatorInherit(name) { 7488 return function() { 7489 var document = this.ownerDocument, 7490 uri = this.namespaceURI; 7491 return uri === xhtml && document.documentElement.namespaceURI === xhtml 7492 ? document.createElement(name) 7493 : document.createElementNS(uri, name); 7494 }; 7495 } 7496 7497 function creatorFixed(fullname) { 7498 return function() { 7499 return this.ownerDocument.createElementNS(fullname.space, fullname.local); 7500 }; 7501 } 7502 7503 function creator(name) { 7504 var fullname = namespace(name); 7505 return (fullname.local 7506 ? creatorFixed 7507 : creatorInherit)(fullname); 7508 } 7509 7510 function none() {} 7511 7512 function selector(selector) { 7513 return selector == null ? none : function() { 7514 return this.querySelector(selector); 7515 }; 7516 } 7517 7518 function selection_select(select) { 7519 if (typeof select !== "function") select = selector(select); 7520 7521 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { 7522 for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { 7523 if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { 7524 if ("__data__" in node) subnode.__data__ = node.__data__; 7525 subgroup[i] = subnode;
7526 } 7527 } 7528 } 7529 7530 return new Selection(subgroups, this._parents); 7531 } 7532 7533 function empty() { 7534 return []; 7535 } 7536 7537 function selectorAll(selector) { 7538 return selector == null ? empty : function() { 7539 return this.querySelectorAll(selector); 7540 }; 7541 } 7542 7543 function selection_selectAll(select) { 7544 if (typeof select !== "function") select = selectorAll(select); 7545 7546 for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { 7547 for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { 7548 if (node = group[i]) { 7549 subgroups.push(select.call(node, node.__data__, i, group)); 7550 parents.push(node); 7551 } 7552 } 7553 } 7554 7555 return new Selection(subgroups, parents); 7556 } 7557 7558 function matcher(selector) { 7559 return function() { 7560 return this.matches(selector); 7561 }; 7562 } 7563 7564 function selection_filter(match) { 7565 if (typeof match !== "function") match = matcher(match); 7566 7567 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { 7568 for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { 7569 if ((node = group[i]) && match.call(node, node.__data__, i, group)) { 7570 subgroup.push(node); 7571 } 7572 } 7573 } 7574 7575 return new Selection(subgroups, this._parents); 7576 } 7577 7578 function sparse(update) { 7579 return new Array(update.length); 7580 } 7581 7582 function selection_enter() { 7583 return new Selection(this._enter || this._groups.map(sparse), this._parents); 7584 } 7585 7586 function EnterNode(parent, datum) { 7587 this.ownerDocument = parent.ownerDocument; 7588 this.namespaceURI = parent.namespaceURI; 7589 this._next = null; 7590 this._parent = parent; 7591 this.__data__ = datum; 7592 } 7593 7594 EnterNode.prototype = { 7595 constructor: EnterNode, 7596 appendChild: function(child) { return this._parent.insertBefore(child, this._next); }, 7597 insertBefore: function(child, next) { return this._parent.insertBefore(child, next); }, 7598 querySelector: function(selector) { return this._parent.querySelector(selector); }, 7599 querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); } 7600 }; 7601 7602 function constant$2(x) { 7603 return function() { 7604 return x; 7605 }; 7606 } 7607 7608 var keyPrefix = "$"; // Protect against keys like â__proto__â. 7609 7610 function bindIndex(parent, group, enter, update, exit, data) { 7611 var i = 0, 7612 node, 7613 groupLength = group.length, 7614 dataLength = data.length; 7615 7616 // Put any non-null nodes that fit into update. 7617 // Put any null nodes into enter. 7618 // Put any remaining data into enter. 7619 for (; i < dataLength; ++i) { 7620 if (node = group[i]) { 7621 node.__data__ = data[i]; 7622 update[i] = node; 7623 } else { 7624 enter[i] = new EnterNode(parent, data[i]); 7625 } 7626 } 7627 7628 // Put any non-null nodes that donât fit into exit. 7629 for (; i < groupLength; ++i) { 7630 if (node = group[i]) { 7631 exit[i] = node; 7632 } 7633 } 7634 } 7635 7636 function bindKey(parent, group, enter, update, exit, data, key) { 7637 var i, 7638 node, 7639 nodeByKeyValue = {}, 7640 groupLength = group.length, 7641 dataLength = data.length, 7642 keyValues = new Array(groupLength), 7643 keyValue; 7644 7645 // Compute the key for each node. 7646 // If multiple nodes have the same key, the duplicates are added to exit. 7647 for (i = 0; i < groupLength; ++i) { 7648 if (node = group[i]) { 7649 keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group); 7650 if (keyValue in nodeByKeyValue) { 7651 exit[i] = node; 7652 } else { 7653 nodeByKeyValue[keyValue] = node; 7654 } 7655 } 7656 } 7657 7658 // Compute the key for each datum. 7659 // If there a node associated with this key, join and add it to update. 7660 // If there is not (or the key is a duplicate), add it to enter. 7661 for (i = 0; i < dataLength; ++i) { 7662 keyValue = keyPrefix + key.call(parent, data[i], i, data); 7663 if (node = nodeByKeyValue[keyValue]) { 7664 update[i] = node; 7665 node.__data__ = data[i]; 7666 nodeByKeyValue[keyValue] = null; 7667 } else { 7668 enter[i] = new EnterNode(parent, data[i]); 7669 } 7670 } 7671 7672 // Add any remaining nodes that were not bound to data to exit. 7673 for (i = 0; i < groupLength; ++i) { 7674 if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) { 7675 exit[i] = node; 7676 } 7677 } 7678 } 7679 7680 function selection_data(value, key) { 7681 if (!value) {
7682 data = new Array(this.size()), j = -1; 7683 this.each(function(d) { data[++j] = d; }); 7684 return data; 7685 } 7686 7687 var bind = key ? bindKey : bindIndex, 7688 parents = this._parents, 7689 groups = this._groups; 7690 7691 if (typeof value !== "function") value = constant$2(value); 7692 7693 for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) { 7694 var parent = parents[j], 7695 group = groups[j], 7696 groupLength = group.length, 7697 data = value.call(parent, parent && parent.__data__, j, parents), 7698 dataLength = data.length, 7699 enterGroup = enter[j] = new Array(dataLength), 7700 updateGroup = update[j] = new Array(dataLength), 7701 exitGroup = exit[j] = new Array(groupLength); 7702 7703 bind(parent, group, enterGroup, updateGroup, exitGroup, data, key); 7704 7705 // Now connect the enter nodes to their following update node, such that 7706 // appendChild can insert the materialized enter node before this node, 7707 // rather than at the end of the parent node. 7708 for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) { 7709 if (previous = enterGroup[i0]) { 7710 if (i0 >= i1) i1 = i0 + 1; 7711 while (!(next = updateGroup[i1]) && ++i1 < dataLength); 7712 previous._next = next || null; 7713 } 7714 } 7715 } 7716 7717 update = new Selection(update, parents); 7718 update._enter = enter; 7719 update._exit = exit; 7720 return update; 7721 } 7722 7723 function selection_exit() { 7724 return new Selection(this._exit || this._groups.map(sparse), this._parents); 7725 } 7726 7727 function selection_join(onenter, onupdate, onexit) { 7728 var enter = this.enter(), update = this, exit = this.exit(); 7729 enter = typeof onenter === "function" ? onenter(enter) : enter.append(onenter + ""); 7730 if (onupdate != null) update = onupdate(update); 7731 if (onexit == null) exit.remove(); else onexit(exit); 7732 return enter && update ? enter.merge(update).order() : update; 7733 } 7734 7735 function selection_merge(selection) { 7736 7737 for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { 7738 for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { 7739 if (node = group0[i] || group1[i]) { 7740 merge[i] = node; 7741 } 7742 } 7743 } 7744 7745 for (; j < m0; ++j) { 7746 merges[j] = groups0[j]; 7747 } 7748 7749 return new Selection(merges, this._parents); 7750 } 7751 7752 function selection_order() { 7753 7754 for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) { 7755 for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) { 7756 if (node = group[i]) { 7757 if (next && node.compareDocumentPosition(next) ^ 4) next.parentNode.insertBefore(node, next); 7758 next = node; 7759 } 7760 } 7761 } 7762 7763 return this; 7764 } 7765 7766 function selection_sort(compare) { 7767 if (!compare) compare = ascending$1; 7768 7769 function compareNode(a, b) { 7770 return a && b ? compare(a.__data__, b.__data__) : !a - !b; 7771 } 7772 7773 for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) { 7774 for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) { 7775 if (node = group[i]) { 7776 sortgroup[i] = node; 7777 } 7778 } 7779 sortgroup.sort(compareNode); 7780 } 7781 7782 return new Selection(sortgroups, this._parents).order(); 7783 } 7784 7785 function ascending$1(a, b) { 7786 return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; 7787 } 7788 7789 function selection_call() { 7790 var callback = arguments[0]; 7791 arguments[0] = this; 7792 callback.apply(null, arguments); 7793 return this; 7794 } 7795 7796 function selection_nodes() { 7797 var nodes = new Array(this.size()), i = -1; 7798 this.each(function() { nodes[++i] = this; }); 7799 return nodes; 7800 } 7801 7802 function selection_node() { 7803 7804 for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { 7805 for (var group = groups[j], i = 0, n = group.length; i < n; ++i) { 7806 var node = group[i]; 7807 if (node) return node; 7808 } 7809 } 7810 7811 return null; 7812 } 7813 7814 function selection_size() { 7815 var size = 0; 7816 this.each(function() { ++size; }); 7817 return size; 7818 } 7819 7820 function selection_empty() { 7821 return !this.node(); 7822 } 7823 7824 function selection_each(callback) { 7825 7826 for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { 7827 for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { 7828 if (node = group[i]) callback.call(node, node.__data__, i, group); 7829 } 7830 } 7831 7832 return this; 7833 } 7834 7835 function attrRemove(name) { 7836 return function() { 7837 this.removeAttribute(name); 7838 }; 7839 } 7840 7841 function attrRemoveNS(fullname) { 7842 return function() { 7843 this.removeAttributeNS(fullname.space, fullname.local); 7844 }; 7845 } 7846 7847 function attrConstant(name, value) { 7848 return function() { 7849 this.setAttribute(name, value); 7850 }; 7851 } 7852 7853 function attrConstantNS(fullname, value) { 7854 return function() { 7855 this.setAttributeNS(fullname.space, fullname.local, value); 7856 }; 7857 } 7858 7859 function attrFunction(name, value) { 7860 return function() {
vendor: 4,535 bytes, lines 7861-8026
7861 var v = value.apply(this, arguments); 7862 if (v == null) this.removeAttribute(name); 7863 else this.setAttribute(name, v); 7864 }; 7865 } 7866 7867 function attrFunctionNS(fullname, value) { 7868 return function() { 7869 var v = value.apply(this, arguments); 7870 if (v == null) this.removeAttributeNS(fullname.space, fullname.local); 7871 else this.setAttributeNS(fullname.space, fullname.local, v); 7872 }; 7873 } 7874 7875 function selection_attr(name, value) { 7876 var fullname = namespace(name); 7877 7878 if (arguments.length < 2) { 7879 var node = this.node(); 7880 return fullname.local 7881 ? node.getAttributeNS(fullname.space, fullname.local) 7882 : node.getAttribute(fullname); 7883 } 7884 7885 return this.each((value == null 7886 ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function" 7887 ? (fullname.local ? attrFunctionNS : attrFunction) 7888 : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value)); 7889 } 7890 7891 function defaultView(node) { 7892 return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node 7893 || (node.document && node) // node is a Window 7894 || node.defaultView; // node is a Document 7895 } 7896 7897 function styleRemove(name) { 7898 return function() { 7899 this.style.removeProperty(name); 7900 }; 7901 } 7902 7903 function styleConstant(name, value, priority) { 7904 return function() { 7905 this.style.setProperty(name, value, priority); 7906 }; 7907 } 7908 7909 function styleFunction(name, value, priority) { 7910 return function() { 7911 var v = value.apply(this, arguments); 7912 if (v == null) this.style.removeProperty(name); 7913 else this.style.setProperty(name, v, priority); 7914 }; 7915 } 7916 7917 function selection_style(name, value, priority) { 7918 return arguments.length > 1 7919 ? this.each((value == null 7920 ? styleRemove : typeof value === "function" 7921 ? styleFunction 7922 : styleConstant)(name, value, priority == null ? "" : priority)) 7923 : styleValue(this.node(), name); 7924 } 7925 7926 function styleValue(node, name) { 7927 return node.style.getPropertyValue(name) 7928 || defaultView(node).getComputedStyle(node, null).getPropertyValue(name); 7929 } 7930 7931 function propertyRemove(name) { 7932 return function() { 7933 delete this[name]; 7934 }; 7935 } 7936 7937 function propertyConstant(name, value) { 7938 return function() { 7939 this[name] = value; 7940 }; 7941 } 7942 7943 function propertyFunction(name, value) { 7944 return function() { 7945 var v = value.apply(this, arguments); 7946 if (v == null) delete this[name]; 7947 else this[name] = v; 7948 }; 7949 } 7950 7951 function selection_property(name, value) { 7952 return arguments.length > 1 7953 ? this.each((value == null 7954 ? propertyRemove : typeof value === "function" 7955 ? propertyFunction 7956 : propertyConstant)(name, value)) 7957 : this.node()[name]; 7958 } 7959 7960 function classArray(string) { 7961 return string.trim().split(/^|\s+/); 7962 } 7963 7964 function classList(node) { 7965 return node.classList || new ClassList(node); 7966 } 7967 7968 function ClassList(node) { 7969 this._node = node; 7970 this._names = classArray(node.getAttribute("class") || ""); 7971 } 7972 7973 ClassList.prototype = { 7974 add: function(name) { 7975 var i = this._names.indexOf(name); 7976 if (i < 0) { 7977 this._names.push(name); 7978 this._node.setAttribute("class", this._names.join(" ")); 7979 } 7980 }, 7981 remove: function(name) { 7982 var i = this._names.indexOf(name); 7983 if (i >= 0) { 7984 this._names.splice(i, 1); 7985 this._node.setAttribute("class", this._names.join(" ")); 7986 } 7987 }, 7988 contains: function(name) { 7989 return this._names.indexOf(name) >= 0; 7990 } 7991 }; 7992 7993 function classedAdd(node, names) { 7994 var list = classList(node), i = -1, n = names.length; 7995 while (++i < n) list.add(names[i]); 7996 } 7997 7998 function classedRemove(node, names) { 7999 var list = classList(node), i = -1, n = names.length; 8000 while (++i < n) list.remove(names[i]); 8001 } 8002 8003 function classedTrue(names) { 8004 return function() { 8005 classedAdd(this, names); 8006 }; 8007 } 8008 8009 function classedFalse(names) { 8010 return function() { 8011 classedRemove(this, names); 8012 }; 8013 } 8014 8015 function classedFunction(names, value) { 8016 return function() { 8017 (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names); 8018 }; 8019 } 8020 8021 function selection_classed(name, value) { 8022 var names = classArray(name + ""); 8023 8024 if (arguments.length < 2) { 8025 var list = classList(this.node()), i = -1, n = names.length; 8026 while (++i < n) if (!list.contains(names[i])) return false;
8027 return true; 8028 } 8029 8030 return this.each((typeof value === "function" 8031 ? classedFunction : value 8032 ? classedTrue 8033 : classedFalse)(names, value)); 8034 } 8035 8036 function textRemove() { 8037 this.textContent = ""; 8038 } 8039 8040 function textConstant(value) { 8041 return function() { 8042 this.textContent = value; 8043 }; 8044 } 8045 8046 function textFunction(value) { 8047 return function() { 8048 var v = value.apply(this, arguments); 8049 this.textContent = v == null ? "" : v; 8050 }; 8051 } 8052 8053 function selection_text(value) { 8054 return arguments.length 8055 ? this.each(value == null 8056 ? textRemove : (typeof value === "function" 8057 ? textFunction 8058 : textConstant)(value)) 8059 : this.node().textContent; 8060 } 8061 8062 function htmlRemove() { 8063 this.innerHTML = ""; 8064 } 8065 8066 function htmlConstant(value) { 8067 return function() { 8068 this.innerHTML = value; 8069 }; 8070 } 8071 8072 function htmlFunction(value) { 8073 return function() { 8074 var v = value.apply(this, arguments); 8075 this.innerHTML = v == null ? "" : v; 8076 }; 8077 } 8078 8079 function selection_html(value) { 8080 return arguments.length 8081 ? this.each(value == null 8082 ? htmlRemove : (typeof value === "function" 8083 ? htmlFunction 8084 : htmlConstant)(value)) 8085 : this.node().innerHTML; 8086 } 8087 8088 function raise() { 8089 if (this.nextSibling) this.parentNode.appendChild(this); 8090 } 8091 8092 function selection_raise() { 8093 return this.each(raise); 8094 } 8095 8096 function lower() { 8097 if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild); 8098 } 8099 8100 function selection_lower() { 8101 return this.each(lower); 8102 } 8103 8104 function selection_append(name) { 8105 var create = typeof name === "function" ? name : creator(name); 8106 return this.select(function() { 8107 return this.appendChild(create.apply(this, arguments)); 8108 }); 8109 } 8110 8111 function constantNull() { 8112 return null; 8113 } 8114 8115 function selection_insert(name, before) { 8116 var create = typeof name === "function" ? name : creator(name), 8117 select = before == null ? constantNull : typeof before === "function" ? before : selector(before); 8118 return this.select(function() { 8119 return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null); 8120 }); 8121 } 8122 8123 function remove() { 8124 var parent = this.parentNode; 8125 if (parent) parent.removeChild(this); 8126 } 8127 8128 function selection_remove() { 8129 return this.each(remove); 8130 } 8131 8132 function selection_cloneShallow() { 8133 var clone = this.cloneNode(false), parent = this.parentNode; 8134 return parent ? parent.insertBefore(clone, this.nextSibling) : clone; 8135 } 8136 8137 function selection_cloneDeep() { 8138 var clone = this.cloneNode(true), parent = this.parentNode; 8139 return parent ? parent.insertBefore(clone, this.nextSibling) : clone; 8140 } 8141 8142 function selection_clone(deep) { 8143 return this.select(deep ? selection_cloneDeep : selection_cloneShallow); 8144 } 8145 8146 function selection_datum(value) { 8147 return arguments.length 8148 ? this.property("__data__", value) 8149 : this.node().__data__; 8150 } 8151 8152 var filterEvents = {}; 8153 8154 var event = null; 8155 8156 if (typeof document !== "undefined") { 8157 var element = document.documentElement; 8158 if (!("onmouseenter" in element)) { 8159 filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"}; 8160 } 8161 } 8162 8163 function filterContextListener(listener, index, group) { 8164 listener = contextListener(listener, index, group); 8165 return function(event) { 8166 var related = event.relatedTarget; 8167 if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) { 8168 listener.call(this, event); 8169 } 8170 }; 8171 } 8172 8173 function contextListener(listener, index, group) { 8174 return function(event1) { 8175 var event0 = event; // Events can be reentrant (e.g., focus). 8176 event = event1; 8177 try { 8178 listener.call(this, this.__data__, index, group); 8179 } finally { 8180 event = event0; 8181 } 8182 }; 8183 } 8184 8185 function parseTypenames$1(typenames) { 8186 return typenames.trim().split(/^|\s+/).map(function(t) { 8187 var name = "", i = t.indexOf("."); 8188 if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); 8189 return {type: t, name: name}; 8190 }); 8191 } 8192 8193 function onRemove(typename) { 8194 return function() { 8195 var on = this.__on; 8196 if (!on) return; 8197 for (var j = 0, i = -1, m = on.length, o; j < m; ++j) { 8198 if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) { 8199 this.removeEventListener(o.type, o.listener, o.capture); 8200 } else { 8201 on[++i] = o; 8202 } 8203 } 8204 if (++i) on.length = i; 8205 else delete this.__on; 8206 }; 8207 } 8208 8209 function onAdd(typename, value, capture) { 8210 var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener; 8211 return function(d, i, group) { 8212 var on = this.__on, o, listener = wrap(value, i, group); 8213 if (on) for (var j = 0, m = on.length; j < m; ++j) { 8214 if ((o = on[j]).type === typename.type && o.name === typename.name) { 8215 this.removeEventListener(o.type, o.listener, o.capture); 8216 this.addEventListener(o.type, o.listener = listener, o.capture = capture); 8217 o.value = value; 8218 return; 8219 } 8220 } 8221 this.addEventListener(typename.type, listener, capture); 8222 o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture}; 8223 if (!on) this.__on = [o]; 8224 else on.push(o); 8225 }; 8226 } 8227 8228 function selection_on(typename, value, capture) { 8229 var typenames = parseTypenames$1(typename + ""), i, n = typenames.length, t; 8230 8231 if (arguments.length < 2) { 8232 var on = this.node().__on; 8233 if (on) for (var j = 0, m = on.length, o; j < m; ++j) { 8234 for (i = 0, o = on[j]; i < n; ++i) { 8235 if ((t = typenames[i]).type === o.type && t.name === o.name) { 8236 return o.value; 8237 } 8238 } 8239 } 8240 return; 8241 } 8242 8243 on = value ? onAdd : onRemove; 8244 if (capture == null) capture = false;
8245 for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture)); 8246 return this; 8247 } 8248 8249 function customEvent(event1, listener, that, args) { 8250 var event0 = event; 8251 event1.sourceEvent = event; 8252 event = event1; 8253 try { 8254 return listener.apply(that, args); 8255 } finally { 8256 event = event0; 8257 } 8258 } 8259 8260 function dispatchEvent(node, type, params) { 8261 var window = defaultView(node), 8262 event = window.CustomEvent; 8263 8264 if (typeof event === "function") { 8265 event = new event(type, params); 8266 } else { 8267 event = window.document.createEvent("Event"); 8268 if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail; 8269 else event.initEvent(type, false, false); 8270 } 8271 8272 node.dispatchEvent(event); 8273 } 8274 8275 function dispatchConstant(type, params) { 8276 return function() { 8277 return dispatchEvent(this, type, params); 8278 }; 8279 } 8280 8281 function dispatchFunction(type, params) { 8282 return function() { 8283 return dispatchEvent(this, type, params.apply(this, arguments)); 8284 }; 8285 } 8286 8287 function selection_dispatch(type, params) { 8288 return this.each((typeof params === "function" 8289 ? dispatchFunction 8290 : dispatchConstant)(type, params)); 8291 } 8292 8293 var root = [null]; 8294 8295 function Selection(groups, parents) { 8296 this._groups = groups; 8297 this._parents = parents; 8298 } 8299 8300 function selection() { 8301 return new Selection([[document.documentElement]], root); 8302 } 8303 8304 Selection.prototype = selection.prototype = { 8305 constructor: Selection, 8306 select: selection_select, 8307 selectAll: selection_selectAll, 8308 filter: selection_filter, 8309 data: selection_data, 8310 enter: selection_enter, 8311 exit: selection_exit, 8312 join: selection_join, 8313 merge: selection_merge, 8314 order: selection_order, 8315 sort: selection_sort, 8316 call: selection_call, 8317 nodes: selection_nodes, 8318 node: selection_node, 8319 size: selection_size, 8320 empty: selection_empty, 8321 each: selection_each, 8322 attr: selection_attr, 8323 style: selection_style, 8324 property: selection_property, 8325 classed: selection_classed, 8326 text: selection_text, 8327 html: selection_html, 8328 raise: selection_raise, 8329 lower: selection_lower, 8330 append: selection_append, 8331 insert: selection_insert, 8332 remove: selection_remove, 8333 clone: selection_clone, 8334 datum: selection_datum, 8335 on: selection_on, 8336 dispatch: selection_dispatch 8337 }; 8338 8339 function select(selector) { 8340 return typeof selector === "string" 8341 ? new Selection([[document.querySelector(selector)]], [document.documentElement]) 8342 : new Selection([[selector]], root); 8343 } 8344 8345 function sourceEvent() { 8346 var current = event, source; 8347 while (source = current.sourceEvent) current = source; 8348 return current; 8349 } 8350 8351 function point(node, event) { 8352 var svg = node.ownerSVGElement || node; 8353 8354 if (svg.createSVGPoint) { 8355 var point = svg.createSVGPoint(); 8356 point.x = event.clientX, point.y = event.clientY; 8357 point = point.matrixTransform(node.getScreenCTM().inverse()); 8358 return [point.x, point.y]; 8359 } 8360 8361 var rect = node.getBoundingClientRect(); 8362 return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop]; 8363 } 8364 8365 function mouse(node) { 8366 var event = sourceEvent(); 8367 if (event.changedTouches) event = event.changedTouches[0]; 8368 return point(node, event); 8369 } 8370 8371 function touch(node, touches, identifier) { 8372 if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches; 8373 8374 for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) { 8375 if ((touch = touches[i]).identifier === identifier) { 8376 return point(node, touch); 8377 } 8378 } 8379 8380 return null; 8381 } 8382 8383 function nopropagation() { 8384 event.stopImmediatePropagation(); 8385 } 8386 8387 function noevent() { 8388 event.preventDefault(); 8389 event.stopImmediatePropagation(); 8390 } 8391 8392 function nodrag(view) { 8393 var root = view.document.documentElement, 8394 selection = select(view).on("dragstart.drag", noevent, true); 8395 if ("onselectstart" in root) { 8396 selection.on("selectstart.drag", noevent, true); 8397 } else { 8398 root.__noselect = root.style.MozUserSelect; 8399 root.style.MozUserSelect = "none"; 8400 } 8401 } 8402 8403 function yesdrag(view, noclick) { 8404 var root = view.document.documentElement, 8405 selection = select(view).on("dragstart.drag", null); 8406 if (noclick) { 8407 selection.on("click.drag", noevent, true); 8408 setTimeout(function() { selection.on("click.drag", null); }, 0); 8409 } 8410 if ("onselectstart" in root) { 8411 selection.on("selectstart.drag", null); 8412 } else { 8413 root.style.MozUserSelect = root.__noselect; 8414 delete root.__noselect; 8415 } 8416 } 8417 8418 function constant$3(x) { 8419 return function() { 8420 return x; 8421 }; 8422 } 8423 8424 function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) { 8425 this.target = target; 8426 this.type = type; 8427 this.subject = subject; 8428 this.identifier = id; 8429 this.active = active; 8430 this.x = x; 8431 this.y = y; 8432 this.dx = dx;
8433 this.dy = dy; 8434 this._ = dispatch; 8435 } 8436 8437 DragEvent.prototype.on = function() { 8438 var value = this._.on.apply(this._, arguments); 8439 return value === this._ ? this : value; 8440 }; 8441 8442 // Ignore right-click, since that should open the context menu. 8443 function defaultFilter() { 8444 return !event.ctrlKey && !event.button; 8445 } 8446 8447 function defaultContainer() { 8448 return this.parentNode; 8449 } 8450 8451 function defaultSubject(d) { 8452 return d == null ? {x: event.x, y: event.y} : d; 8453 } 8454 8455 function defaultTouchable() { 8456 return navigator.maxTouchPoints || ("ontouchstart" in this); 8457 } 8458 8459 function drag() { 8460 var filter = defaultFilter, 8461 container = defaultContainer, 8462 subject = defaultSubject, 8463 touchable = defaultTouchable, 8464 gestures = {}, 8465 listeners = dispatch("start", "drag", "end"), 8466 active = 0, 8467 mousedownx, 8468 mousedowny, 8469 mousemoving, 8470 touchending, 8471 clickDistance2 = 0; 8472 8473 function drag(selection) { 8474 selection 8475 .on("mousedown.drag", mousedowned) 8476 .filter(touchable) 8477 .on("touchstart.drag", touchstarted) 8478 .on("touchmove.drag", touchmoved) 8479 .on("touchend.drag touchcancel.drag", touchended) 8480 .style("touch-action", "none") 8481 .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); 8482 } 8483 8484 function mousedowned() { 8485 if (touchending || !filter.apply(this, arguments)) return; 8486 var gesture = beforestart("mouse", container.apply(this, arguments), mouse, this, arguments); 8487 if (!gesture) return; 8488 select(event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true); 8489 nodrag(event.view); 8490 nopropagation(); 8491 mousemoving = false; 8492 mousedownx = event.clientX; 8493 mousedowny = event.clientY; 8494 gesture("start"); 8495 } 8496 8497 function mousemoved() { 8498 noevent(); 8499 if (!mousemoving) { 8500 var dx = event.clientX - mousedownx, dy = event.clientY - mousedowny; 8501 mousemoving = dx * dx + dy * dy > clickDistance2; 8502 } 8503 gestures.mouse("drag"); 8504 } 8505 8506 function mouseupped() { 8507 select(event.view).on("mousemove.drag mouseup.drag", null); 8508 yesdrag(event.view, mousemoving); 8509 noevent(); 8510 gestures.mouse("end"); 8511 } 8512 8513 function touchstarted() { 8514 if (!filter.apply(this, arguments)) return; 8515 var touches = event.changedTouches, 8516 c = container.apply(this, arguments), 8517 n = touches.length, i, gesture; 8518 8519 for (i = 0; i < n; ++i) { 8520 if (gesture = beforestart(touches[i].identifier, c, touch, this, arguments)) { 8521 nopropagation(); 8522 gesture("start"); 8523 } 8524 } 8525 } 8526 8527 function touchmoved() { 8528 var touches = event.changedTouches, 8529 n = touches.length, i, gesture; 8530 8531 for (i = 0; i < n; ++i) { 8532 if (gesture = gestures[touches[i].identifier]) { 8533 noevent(); 8534 gesture("drag"); 8535 } 8536 } 8537 } 8538 8539 function touchended() { 8540 var touches = event.changedTouches, 8541 n = touches.length, i, gesture; 8542 8543 if (touchending) clearTimeout(touchending); 8544 touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed! 8545 for (i = 0; i < n; ++i) { 8546 if (gesture = gestures[touches[i].identifier]) { 8547 nopropagation(); 8548 gesture("end"); 8549 } 8550 } 8551 } 8552 8553 function beforestart(id, container, point, that, args) { 8554 var p = point(container, id), s, dx, dy, 8555 sublisteners = listeners.copy(); 8556 8557 if (!customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() { 8558 if ((event.subject = s = subject.apply(that, args)) == null) return false; 8559 dx = s.x - p[0] || 0; 8560 dy = s.y - p[1] || 0; 8561 return true; 8562 })) return; 8563 8564 return function gesture(type) { 8565 var p0 = p, n; 8566 switch (type) { 8567 case "start": gestures[id] = gesture, n = active++; break; 8568 case "end": delete gestures[id], --active; // nobreak 8569 case "drag": p = point(container, id), n = active; break; 8570 } 8571 customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]); 8572 }; 8573 } 8574 8575 drag.filter = function(_) { 8576 return arguments.length ? (filter = typeof _ === "function" ? _ : constant$3(!!_), drag) : filter; 8577 }; 8578 8579 drag.container = function(_) { 8580 return arguments.length ? (container = typeof _ === "function" ? _ : constant$3(_), drag) : container; 8581 }; 8582 8583 drag.subject = function(_) { 8584 return arguments.length ? (subject = typeof _ === "function" ? _ : constant$3(_), drag) : subject; 8585 }; 8586 8587 drag.touchable = function(_) { 8588 return arguments.length ? (touchable = typeof _ === "function" ? _ : constant$3(!!_), drag) : touchable; 8589 }; 8590 8591 drag.on = function() { 8592 var value = listeners.on.apply(listeners, arguments); 8593 return value === listeners ? drag : value; 8594 }; 8595 8596 drag.clickDistance = function(_) { 8597 return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2); 8598 }; 8599 8600 return drag; 8601 } 8602 8603 // Copyright 2018 The Distill Template Authors 8604
8605 const T$a = Template('d-slider', ` 8606<style> 8607 :host { 8608 position: relative; 8609 display: inline-block; 8610 } 8611 8612 :host(:focus) { 8613 outline: none; 8614 } 8615 8616 .background { 8617 padding: 9px 0; 8618 color: white; 8619 position: relative; 8620 } 8621 8622 .track { 8623 height: 3px; 8624 width: 100%; 8625 border-radius: 2px; 8626 background-color: hsla(0, 0%, 0%, 0.2); 8627 } 8628 8629 .track-fill { 8630 position: absolute; 8631 top: 9px; 8632 height: 3px; 8633 border-radius: 4px; 8634 background-color: hsl(24, 100%, 50%); 8635 } 8636 8637 .knob-container { 8638 position: absolute; 8639 top: 10px; 8640 } 8641 8642 .knob { 8643 position: absolute; 8644 top: -6px; 8645 left: -6px; 8646 width: 13px; 8647 height: 13px; 8648 background-color: hsl(24, 100%, 50%); 8649 border-radius: 50%; 8650 transition-property: transform; 8651 transition-duration: 0.18s; 8652 transition-timing-function: ease; 8653 } 8654 .mousedown .knob { 8655 transform: scale(1.5); 8656 } 8657 8658 .knob-highlight { 8659 position: absolute; 8660 top: -6px; 8661 left: -6px; 8662 width: 13px; 8663 height: 13px; 8664 background-color: hsla(0, 0%, 0%, 0.1); 8665 border-radius: 50%; 8666 transition-property: transform; 8667 transition-duration: 0.18s; 8668 transition-timing-function: ease; 8669 } 8670 8671 .focus .knob-highlight { 8672 transform: scale(2); 8673 } 8674 8675 .ticks { 8676 position: absolute; 8677 top: 16px; 8678 height: 4px; 8679 width: 100%; 8680 z-index: -1; 8681 } 8682 8683 .ticks .tick { 8684 position: absolute; 8685 height: 100%; 8686 border-left: 1px solid hsla(0, 0%, 0%, 0.2); 8687 } 8688 8689</style> 8690 8691 <div class='background'> 8692 <div class='track'></div> 8693 <div class='track-fill'></div> 8694 <div class='knob-container'> 8695 <div class='knob-highlight'></div> 8696 <div class='knob'></div> 8697 </div> 8698 <div class='ticks'></div> 8699 </div> 8700`); 8701 8702 // ARIA 8703 // If the slider has a visible label, it is referenced by aria-labelledby on the slider element. Otherwise, the slider element has a label provided by aria-label. 8704 // If the slider is vertically oriented, it has aria-orientation set to vertical. The default value of aria-orientation for a slider is horizontal. 8705 8706 const keyCodes = { 8707 left: 37, 8708 up: 38, 8709 right: 39, 8710 down: 40, 8711 pageUp: 33, 8712 pageDown: 34, 8713 end: 35, 8714 home: 36 8715 }; 8716 8717 class Slider extends T$a(HTMLElement) { 8718 8719 8720 connectedCallback() { 8721 this.connected = true; 8722 this.setAttribute('role', 'slider'); 8723 // Makes the element tab-able. 8724 if (!this.hasAttribute('tabindex')) { this.setAttribute('tabindex', 0); } 8725 8726 // Keeps track of keyboard vs. mouse interactions for focus rings 8727 this.mouseEvent = false; 8728 8729 // Handles to shadow DOM elements 8730 this.knob = this.root.querySelector('.knob-container'); 8731 this.background = this.root.querySelector('.background'); 8732 this.trackFill = this.root.querySelector('.track-fill'); 8733 this.track = this.root.querySelector('.track'); 8734 8735 // Default values for attributes 8736 this.min = this.min ? this.min : 0; 8737 this.max = this.max ? this.max : 100; 8738 this.scale = linear$1().domain([this.min, this.max]).range([0, 1]).clamp(true); 8739 8740 this.origin = this.origin !== undefined ? this.origin : this.min; 8741 this.step = this.step ? this.step : 1; 8742 this.update(this.value ? this.value : 0); 8743 8744 this.ticks = this.ticks ? this.ticks : false; 8745 this.renderTicks(); 8746 8747 this.drag = drag() 8748 .container(this.background) 8749 .on('start', () => { 8750 this.mouseEvent = true; 8751 this.background.classList.add('mousedown'); 8752 this.changeValue = this.value; 8753 this.dragUpdate(); 8754 }) 8755 .on('drag', () => { 8756 this.dragUpdate(); 8757 }) 8758 .on('end', () => { 8759 this.mouseEvent = false; 8760 this.background.classList.remove('mousedown'); 8761 this.dragUpdate(); 8762 if (this.changeValue !== this.value) this.dispatchChange(); 8763 this.changeValue = this.value; 8764 }); 8765 this.drag(select(this.background)); 8766 8767 this.addEventListener('focusin', () => { 8768 if(!this.mouseEvent) { 8769 this.background.classList.add('focus'); 8770 } 8771 }); 8772 this.addEventListener('focusout', () => { 8773 this.background.classList.remove('focus'); 8774 }); 8775 this.addEventListener('keydown', this.onKeyDown); 8776 8777 } 8778 8779 static get observedAttributes() {return ['min', 'max', 'value', 'step', 'ticks', 'origin', 'tickValues', 'tickLabels']; } 8780 8781 attributeChangedCallback(attr, oldValue, newValue) { 8782 if (isNaN(newValue) || newValue === undefined || newValue === null) return; 8783 if (attr == 'min') { 8784 this.min = +newValue; 8785 this.setAttribute('aria-valuemin', this.min); 8786 } 8787 if (attr == 'max') { 8788 this.max = +newValue; 8789 this.setAttribute('aria-valuemax', this.max); 8790 } 8791 if (attr == 'value') { 8792 this.update(+newValue); 8793 } 8794 if (attr == 'origin') { 8795 this.origin = +newValue; 8796 // this.update(this.value); 8797 } 8798 if (attr == 'step') { 8799 if (newValue > 0) { 8800 this.step = +newValue; 8801 } 8802 } 8803 if (attr == 'ticks') { 8804 this.ticks = (newValue === '' ? true : newValue); 8805 } 8806 } 8807 8808 onKeyDown(event) { 8809 this.changeValue = this.value; 8810 let stopPropagation = false;
8811 switch (event.keyCode) { 8812 case keyCodes.left: 8813 case keyCodes.down: 8814 this.update(this.value - this.step); 8815 stopPropagation = true; 8816 break; 8817 case keyCodes.right: 8818 case keyCodes.up: 8819 this.update(this.value + this.step); 8820 stopPropagation = true; 8821 break; 8822 case keyCodes.pageUp: 8823 this.update(this.value + this.step * 10); 8824 stopPropagation = true; 8825 break; 8826 8827 case keyCodes.pageDown: 8828 this.update(this.value + this.step * 10); 8829 stopPropagation = true; 8830 break; 8831 case keyCodes.home: 8832 this.update(this.min); 8833 stopPropagation = true; 8834 break; 8835 case keyCodes.end: 8836 this.update(this.max); 8837 stopPropagation = true; 8838 break; 8839 } 8840 if (stopPropagation) { 8841 this.background.classList.add('focus'); 8842 event.preventDefault(); 8843 event.stopPropagation(); 8844 if (this.changeValue !== this.value) this.dispatchChange(); 8845 } 8846 } 8847 8848 validateValueRange(min, max, value) { 8849 return Math.max(Math.min(max, value), min); 8850 } 8851 8852 quantizeValue(value, step) { 8853 return Math.round(value / step) * step; 8854 } 8855 8856 dragUpdate() { 8857 const bbox = this.background.getBoundingClientRect(); 8858 const x = event.x; 8859 const width = bbox.width; 8860 this.update(this.scale.invert(x / width)); 8861 } 8862 8863 update(value) { 8864 let v = value; 8865 if (this.step !== 'any') { 8866 v = this.quantizeValue(value, this.step); 8867 } 8868 v = this.validateValueRange(this.min, this.max, v); 8869 if (this.connected) { 8870 this.knob.style.left = this.scale(v) * 100 + '%'; 8871 this.trackFill.style.width = this.scale(this.min + Math.abs(v - this.origin)) * 100 + '%'; 8872 this.trackFill.style.left = this.scale(Math.min(v, this.origin)) * 100 + '%'; 8873 } 8874 if (this.value !== v) { 8875 this.value = v; 8876 this.setAttribute('aria-valuenow', this.value); 8877 this.dispatchInput(); 8878 } 8879 } 8880 8881 // Dispatches only on a committed change (basically only on mouseup). 8882 dispatchChange() { 8883 const e = new Event('change'); 8884 this.dispatchEvent(e, {}); 8885 } 8886 8887 // Dispatches on each value change. 8888 dispatchInput() { 8889 const e = new Event('input'); 8890 this.dispatchEvent(e, {}); 8891 } 8892 8893 renderTicks() { 8894 const ticksContainer = this.root.querySelector('.ticks'); 8895 if (this.ticks !== false) { 8896 let tickData = []; 8897 if (this.ticks > 0) { 8898 tickData = this.scale.ticks(this.ticks); 8899 } else if (this.step === 'any') { 8900 tickData = this.scale.ticks(); 8901 } else { 8902 tickData = range(this.min, this.max + 1e-6, this.step); 8903 } 8904 tickData.forEach(d => { 8905 const tick = document.createElement('div'); 8906 tick.classList.add('tick'); 8907 tick.style.left = this.scale(d) * 100 + '%'; 8908 ticksContainer.appendChild(tick); 8909 }); 8910 } else { 8911 ticksContainer.style.display = 'none'; 8912 } 8913 } 8914 } 8915 8916 var logo = "<svg viewBox=\"-607 419 64 64\">\n <path d=\"M-573.4,478.9c-8,0-14.6-6.4-14.6-14.5s14.6-25.9,14.6-40.8c0,14.9,14.6,32.8,14.6,40.8S-565.4,478.9-573.4,478.9z\"/>\n</svg>\n"; 8917 8918 const headerTemplate = ` 8919<style> 8920distill-header { 8921 position: relative; 8922 height: 60px; 8923 background-color: hsl(200, 60%, 15%); 8924 width: 100%; 8925 box-sizing: border-box; 8926 z-index: 2; 8927 color: rgba(0, 0, 0, 0.8); 8928 border-bottom: 1px solid rgba(0, 0, 0, 0.08); 8929 box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05); 8930} 8931distill-header .content { 8932 height: 70px; 8933 grid-column: page; 8934} 8935distill-header a { 8936 font-size: 16px; 8937 height: 60px; 8938 line-height: 60px; 8939 text-decoration: none; 8940 color: rgba(255, 255, 255, 0.8); 8941 padding: 22px 0; 8942} 8943distill-header a:hover { 8944 color: rgba(255, 255, 255, 1); 8945} 8946distill-header svg { 8947 width: 24px; 8948 position: relative; 8949 top: 4px; 8950 margin-right: 2px; 8951} 8952@media(min-width: 1080px) { 8953 distill-header { 8954 height: 70px; 8955 } 8956 distill-header a { 8957 height: 70px; 8958 line-height: 70px; 8959 padding: 28px 0; 8960 } 8961 distill-header .logo { 8962 } 8963} 8964distill-header svg path { 8965 fill: none; 8966 stroke: rgba(255, 255, 255, 0.8); 8967 stroke-width: 3px; 8968} 8969distill-header .logo { 8970 font-size: 17px; 8971 font-weight: 200; 8972} 8973distill-header .nav { 8974 float: right; 8975 font-weight: 300; 8976} 8977distill-header .nav a { 8978 font-size: 12px; 8979 margin-left: 24px; 8980 text-transform: uppercase; 8981} 8982</style> 8983<div class="content"> 8984 <a href="/" class="logo"> 8985 ${logo} 8986 Distill 8987 </a> 8988 <nav class="nav"> 8989 <a href="/about/">About</a> 8990 <a href="/prize/">Prize</a> 8991 <a href="/journal/">Submit</a> 8992 </nav> 8993</div> 8994`; 8995 8996 // Copyright 2018 The Distill Template Authors 8997 8998 const T$b = Template('distill-header', headerTemplate, false); 8999 9000 class DistillHeader extends T$b(HTMLElement) { 9001 9002 } 9003 9004 // Copyright 2018 The Distill Template Authors 9005 9006 const styles$2 = ` 9007<style> 9008 distill-appendix { 9009 contain: layout style; 9010 } 9011 9012 distill-appendix .citation { 9013 font-size: 11px; 9014 line-height: 15px; 9015 border-left: 1px solid rgba(0, 0, 0, 0.1); 9016 padding-left: 18px; 9017 border: 1px solid rgba(0,0,0,0.1); 9018 background: rgba(0, 0, 0, 0.02); 9019 padding: 10px 18px; 9020 border-radius: 3px; 9021 color: rgba(150, 150, 150, 1); 9022 overflow: hidden; 9023 margin-top: -12px; 9024 white-space: pre-wrap; 9025 word-wrap: break-word; 9026 } 9027 9028 distill-appendix > * { 9029 grid-column: text; 9030 } 9031</style> 9032`; 9033 9034 function appendixTemplate(frontMatter) { 9035 let html = styles$2; 9036 9037 if (typeof frontMatter.githubUrl !== 'undefined') { 9038 html += ` 9039 <h3 id="updates-and-corrections">Updates and Corrections</h3> 9040 <p>`; 9041 if (frontMatter.githubCompareUpdatesUrl) { 9042 html += `<a href="${frontMatter.githubCompareUpdatesUrl}">View all changes</a> to this article since it was first published.`; 9043 } 9044 html += ` 9045 If you see mistakes or want to suggest changes, please <a href="${frontMatter.githubUrl + '/issues/new'}">create an issue on GitHub</a>. </p> 9046 `; 9047 } 9048 9049 const journal = frontMatter.journal; 9050 if (typeof journal !== 'undefined' && journal.title === 'Distill') { 9051 html += ` 9052 <h3 id="reuse">Reuse</h3> 9053 <p>
9053Diagrams and text are licensed under Creative Commons Attribution <a href="https://creativecommons.org/licenses/by/4.0/">CC-BY 4.0</a> with the <a class="github" href="${frontMatter.githubUrl}">source available on GitHub</a>, unless noted otherwise. The figures that have been reused from other sources donât fall under this license and can be recognized by a note in their caption: âFigure from â¦â.</p> 9054 `; 9055 } 9056 9057 if (typeof frontMatter.publishedDate !== 'undefined') { 9058 html += ` 9059 <h3 id="citation">Citation</h3> 9060 <p>For attribution in academic contexts, please cite this work as</p> 9061 <pre class="citation short">${frontMatter.concatenatedAuthors}, "${frontMatter.title}", Distill, ${frontMatter.publishedYear}.</pre> 9062 <p>BibTeX citation</p> 9063 <pre class="citation long">${serializeFrontmatterToBibtex(frontMatter)}</pre> 9064 `; 9065 } 9066 9067 return html; 9068 } 9069 9070 class DistillAppendix extends HTMLElement { 9071 9072 static get is() { return 'distill-appendix'; } 9073 9074 set frontMatter(frontMatter) { 9075 this.innerHTML = appendixTemplate(frontMatter); 9076 } 9077 9078 } 9079 9080 const footerTemplate = ` 9081<style> 9082 9083:host { 9084 color: rgba(255, 255, 255, 0.5); 9085 font-weight: 300; 9086 padding: 2rem 0; 9087 border-top: 1px solid rgba(0, 0, 0, 0.1); 9088 background-color: hsl(180, 5%, 15%); /*hsl(200, 60%, 15%);*/ 9089 text-align: left; 9090 contain: content; 9091} 9092 9093.footer-container .logo svg { 9094 width: 24px; 9095 position: relative; 9096 top: 4px; 9097 margin-right: 2px; 9098} 9099 9100.footer-container .logo svg path { 9101 fill: none; 9102 stroke: rgba(255, 255, 255, 0.8); 9103 stroke-width: 3px; 9104} 9105 9106.footer-container .logo { 9107 font-size: 17px; 9108 font-weight: 200; 9109 color: rgba(255, 255, 255, 0.8); 9110 text-decoration: none; 9111 margin-right: 6px; 9112} 9113 9114.footer-container { 9115 grid-column: text; 9116} 9117 9118.footer-container .nav { 9119 font-size: 0.9em; 9120 margin-top: 1.5em; 9121} 9122 9123.footer-container .nav a { 9124 color: rgba(255, 255, 255, 0.8); 9125 margin-right: 6px; 9126 text-decoration: none; 9127} 9128 9129</style> 9130 9131<div class='footer-container'> 9132 9133 <a href="/" class="logo"> 9134 ${logo} 9135 Distill 9136 </a> is dedicated to clear explanations of machine learning 9137 9138 <div class="nav"> 9139 <a href="https://distill.pub/about/">About</a> 9140 <a href="https://distill.pub/journal/">Submit</a> 9141 <a href="https://distill.pub/prize/">Prize</a> 9142 <a href="https://distill.pub/archive/">Archive</a> 9143 <a href="https://distill.pub/rss.xml">RSS</a> 9144 <a href="https://github.com/distillpub">GitHub</a> 9145 <a href="https://twitter.com/distillpub">Twitter</a> 9146 ISSN 2476-0757 9147 </div> 9148 9149</div> 9150 9151`; 9152 9153 // Copyright 2018 The Distill Template Authors 9154 9155 const T$c = Template('distill-footer', footerTemplate); 9156 9157 class DistillFooter extends T$c(HTMLElement) { 9158 9159 } 9160 9161 // Copyright 2018 The Distill Template Authors 9162 9163 let templateIsLoading = false; 9164 let runlevel = 0; 9165 const initialize = function() { 9166 if (window.distill.runlevel < 1) { 9167 throw new Error("Insufficient Runlevel for Distill Template!"); 9168 } 9169 9170 /* 1. Flag that we're being loaded */ 9171 if ("distill" in window && window.distill.templateIsLoading) { 9172 throw new Error( 9173 "Runlevel 1: Distill Template is getting loaded more than once, aborting!" 9174 ); 9175 } else { 9176 window.distill.templateIsLoading = true; 9177 console.debug("Runlevel 1: Distill Template has started loading."); 9178 } 9179 9180 /* 2. Add styles if they weren't added during prerendering */ 9181 makeStyleTag(document); 9182 console.debug("Runlevel 1: Static Distill styles have been added."); 9183 console.debug("Runlevel 1->2."); 9184 window.distill.runlevel += 1; 9185 9186 /* 3. Register Controller listener functions */ 9187 /* Needs to happen before components to their connected callbacks have a controller to talk to. */ 9188 for (const [functionName, callback] of Object.entries(Controller.listeners)) { 9189 if (typeof callback === "function") { 9190 document.addEventListener(functionName, callback); 9191 } else { 9192 console.error("Runlevel 2: Controller listeners need to be functions!"); 9193 } 9194 } 9195 console.debug("Runlevel 2: We can now listen to controller events.");
9196 console.debug("Runlevel 2->3."); 9197 window.distill.runlevel += 1; 9198 9199 /* 4. Register components */ 9200 const components = [ 9201 Abstract, Appendix, Article, Bibliography, Byline, Cite, CitationList, Code, 9202 Footnote, FootnoteList, FrontMatter$1, HoverBox, Title, DMath, References, TOC, Figure, 9203 Slider, Interstitial 9204 ]; 9205 9206 const distillComponents = [DistillHeader, DistillAppendix, DistillFooter]; 9207 9208 if (window.distill.runlevel < 2) { 9209 throw new Error("Insufficient Runlevel for adding custom elements!"); 9210 } 9211 const allComponents = components.concat(distillComponents); 9212 for (const component of allComponents) { 9213 console.debug("Runlevel 2: Registering custom element: " + component.is); 9214 customElements.define(component.is, component); 9215 } 9216 9217 console.debug( 9218 "Runlevel 3: Distill Template finished registering custom elements." 9219 ); 9220 console.debug("Runlevel 3->4."); 9221 window.distill.runlevel += 1; 9222 9223 // If template was added after DOMContentLoaded we may have missed that event. 9224 // Controller will check for that case, so trigger the event explicitly: 9225 if (domContentLoaded()) { 9226 Controller.listeners.DOMContentLoaded(); 9227 } 9228 9229 console.debug("Runlevel 4: Distill Template initialisation complete."); 9230 window.distill.templateIsLoading = false; 9231 window.distill.templateHasLoaded = true; 9232 }; 9233 9234 window.distill = { runlevel, initialize, templateIsLoading }; 9235 9236 /* 0. Check browser feature support; synchronously polyfill if needed */ 9237 if (Polyfills.browserSupportsAllFeatures()) { 9238 console.debug("Runlevel 0: No need for polyfills."); 9239 console.debug("Runlevel 0->1."); 9240 window.distill.runlevel += 1; 9241 window.distill.initialize(); 9242 } else { 9243 console.debug("Runlevel 0: Distill Template is loading polyfills."); 9244 Polyfills.load(window.distill.initialize); 9245 } 9246 9247}))); 9248//# sourceMappingURL=template.v2.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.