1var main; 2(self["webpackChunkmauricio_poppe_blog"] = self["webpackChunkmauricio_poppe_blog"] || []).push([[792],{ 3 4/***/ 267: 5/***/ ((module) => { 6 7function debounce(func, wait, immediate) { 8 var timeout, args, context, timestamp, result; 9 if (null == wait) wait = 100; 10 function later() { 11 var last = Date.now() - timestamp; 12 if (last < wait && last >= 0) { 13 timeout = setTimeout(later, wait - last); 14 } else { 15 timeout = null; 16 if (!immediate) { 17 result = func.apply(context, args); 18 context = args = null; 19 } 20 } 21 } 22 ; 23 var debounced = function() { 24 context = this; 25 args = arguments; 26 timestamp = Date.now(); 27 var callNow = immediate && !timeout; 28 if (!timeout) timeout = setTimeout(later, wait); 29 if (callNow) { 30 result = func.apply(context, args); 31 context = args = null; 32 } 33 return result; 34 }; 35 debounced.clear = function() { 36 if (timeout) { 37 clearTimeout(timeout); 38 timeout = null; 39 } 40 }; 41 debounced.flush = function() { 42 if (timeout) { 43 result = func.apply(context, args); 44 context = args = null; 45 clearTimeout(timeout); 46 timeout = null; 47 } 48 }; 49 return debounced; 50} 51; 52debounce.debounce = debounce; 53module.exports = debounce; 54 55 56/***/ }), 57 58/***/ 557: 59/***/ ((module) => { 60 61"use strict"; 62 63module.exports = isMobile; 64module.exports.isMobile = isMobile; 65module.exports["default"] = isMobile; 66var mobileRE = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series[46]0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i; 67var tabletRE = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series[46]0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino|android|ipad|playbook|silk/i; 68function isMobile(opts) { 69 if (!opts) opts = {}; 70 var ua = opts.ua; 71 if (!ua && typeof navigator !== "undefined") ua = navigator.userAgent; 72 if (ua && ua.headers && typeof ua.headers["user-agent"] === "string") { 73 ua = ua.headers["user-agent"]; 74 } 75 if (typeof ua !== "string") return false; 76 var result = opts.tablet ? tabletRE.test(ua) : mobileRE.test(ua); 77 if (!result && opts.tablet && opts.featureDetect && navigator && navigator.maxTouchPoints > 1 && ua.indexOf("Macintosh") !== -1 && ua.indexOf("Safari") !== -1) { 78 result = true; 79 } 80 return result; 81} 82 83 84/***/ }), 85 86/***/ 285: 87/***/ (function(module) { 88 89/*! lozad.js - v1.0.2 - 2017-09-10 90* https://github.com/ApoorvSaxena/lozad.js 91* Copyright (c) 2017 Apoorv Saxena; Licensed MIT */ 92(function(global, factory) { 93 true ? module.exports = factory() : 0; 94})(this, function() { 95 "use strict"; 96 var _extends = Object.assign || function(target) { 97 for (var i = 1; i < arguments.length; i++) { 98 var source = arguments[i]; 99 for (var key in source) { 100 if (Object.prototype.hasOwnProperty.call(source, key)) { 101 target[key] = source[key]; 102 } 103 } 104 } 105 return target; 106 }; 107 var defaultConfig = { 108 rootMargin: "0px", 109 threshold: 0, 110 load: function load(element) { 111 element.src = element.dataset.src; 112 } 113 }; 114 function markAsLoaded(element) { 115 element.dataset.loaded = true; 116 } 117 var isLoaded = function isLoaded2(element) { 118 return element.dataset.loaded === "true"; 119 }; 120 var onIntersection = function onIntersection2(load) { 121 return function(entries, observer) { 122 entries.forEach(function(entry) { 123 if (entry.intersectionRatio > 0) { 124 observer.unobserve(entry.target); 125 load(entry.target); 126 markAsLoaded(entry.target); 127 } 128 }); 129 }; 130 }; 131 var lozad = function() { 132 var selector = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : ".lozad"; 133 var options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; 134 var _defaultConfig$option = _extends({}, defaultConfig, options), rootMargin = _defaultConfig$option.rootMargin, threshold = _defaultConfig$option.threshold, load = _defaultConfig$option.load; 135 var observer = void 0; 136 if (window.IntersectionObserver) { 137 observer = new IntersectionObserver(onIntersection(load), { 138 rootMargin, 139 threshold 140 }); 141 } 142 return { 143 observe: function observe() { 144 var elements = [].filter.call(document.querySelectorAll(selector), function(element) { 145 return !isLoaded(element); 146 }); 147 if (!observer) {
148 elements.forEach(function(element) { 149 load(element); 150 markAsLoaded(element); 151 }); 152 return; 153 } 154 elements.forEach(function(element) { 155 observer.observe(element); 156 }); 157 } 158 }; 159 }; 160 return lozad; 161}); 162 163 164/***/ }), 165 166/***/ 624: 167/***/ ((module) => { 168 169module.exports = function(options) { 170 var forEach = [].forEach; 171 var some = [].some; 172 var body = document.body; 173 var tocElement; 174 var currentlyHighlighting = true; 175 var SPACE_CHAR = " "; 176 function createEl(d, container) { 177 var link = container.appendChild(createLink(d)); 178 if (d.children.length) { 179 var list = createList(d.isCollapsed); 180 d.children.forEach(function(child) { 181 createEl(child, list); 182 }); 183 link.appendChild(list); 184 } 185 } 186 function render(parent, data) { 187 var collapsed = false; 188 var container = createList(collapsed); 189 data.forEach(function(d) { 190 createEl(d, container); 191 }); 192 tocElement = parent || tocElement; 193 if (tocElement === null) { 194 return; 195 } 196 if (tocElement.firstChild) { 197 tocElement.removeChild(tocElement.firstChild); 198 } 199 if (data.length === 0) { 200 return tocElement; 201 } 202 return tocElement.appendChild(container); 203 } 204 function createLink(data) { 205 var item = document.createElement("li"); 206 var a = document.createElement("a"); 207 if (options.listItemClass) { 208 item.setAttribute("class", options.listItemClass); 209 } 210 if (options.onClick) { 211 a.onclick = options.onClick; 212 } 213 if (options.includeTitleTags) { 214 a.setAttribute("title", data.textContent); 215 } 216 if (options.includeHtml && data.childNodes.length) { 217 forEach.call(data.childNodes, function(node) { 218 a.appendChild(node.cloneNode(true)); 219 }); 220 } else { 221 a.textContent = data.textContent; 222 } 223 a.setAttribute("href", options.basePath + "#" + data.id); 224 a.setAttribute("class", options.linkClass + SPACE_CHAR + "node-name--" + data.nodeName + SPACE_CHAR + options.extraLinkClasses); 225 item.appendChild(a); 226 return item; 227 } 228 function createList(isCollapsed) { 229 var listElement = options.orderedList ? "ol" : "ul"; 230 var list = document.createElement(listElement); 231 var classes = options.listClass + SPACE_CHAR + options.extraListClasses; 232 if (isCollapsed) { 233 classes = classes + SPACE_CHAR + options.collapsibleClass; 234 classes = classes + SPACE_CHAR + options.isCollapsedClass; 235 } 236 list.setAttribute("class", classes); 237 return list; 238 } 239 function updateFixedSidebarClass() { 240 if (options.scrollContainer && document.querySelector(options.scrollContainer)) { 241 var top; 242 top = document.querySelector(options.scrollContainer).scrollTop; 243 } else { 244 top = document.documentElement.scrollTop || body.scrollTop; 245 } 246 var posFixedEl = document.querySelector(options.positionFixedSelector); 247 if (options.fixedSidebarOffset === "auto") { 248 options.fixedSidebarOffset = tocElement.offsetTop; 249 } 250 if (top > options.fixedSidebarOffset) { 251 if (posFixedEl.className.indexOf(options.positionFixedClass) === -1) { 252 posFixedEl.className += SPACE_CHAR + options.positionFixedClass; 253 } 254 } else { 255 posFixedEl.className = posFixedEl.className.split(SPACE_CHAR + options.positionFixedClass).join(""); 256 } 257 } 258 function getHeadingTopPos(obj) { 259 var position = 0; 260 if (obj !== null) { 261 position = obj.offsetTop; 262 if (options.hasInnerContainers) { 263 position += getHeadingTopPos(obj.offsetParent); 264 } 265 } 266 return position; 267 } 268 function updateToc(headingsArray) { 269 if (options.scrollContainer && document.querySelector(options.scrollContainer)) { 270 var top; 271 top = document.querySelector(options.scrollContainer).scrollTop; 272 } else { 273 top = document.documentElement.scrollTop || body.scrollTop; 274 } 275 if (options.positionFixedSelector) { 276 updateFixedSidebarClass(); 277 } 278 var headings = headingsArray; 279 var topHeader; 280 if (currentlyHighlighting && tocElement !== null && headings.length > 0) { 281 some.call(headings, function(heading, i) { 282 if (getHeadingTopPos(heading) > top + options.headingsOffset + 10) {
283 var index = i === 0 ? i : i - 1; 284 topHeader = headings[index]; 285 return true; 286 } else if (i === headings.length - 1) { 287 topHeader = headings[headings.length - 1]; 288 return true; 289 } 290 }); 291 var oldActiveTocLink = tocElement.querySelector("." + options.activeLinkClass); 292 var activeTocLink = tocElement.querySelector("." + options.linkClass + ".node-name--" + topHeader.nodeName + '[href="' + options.basePath + "#" + topHeader.id.replace(/([ #;&,.+*~':"!^$[\]()=>|/\\@])/g, "\\$1") + '"]'); 293 if (oldActiveTocLink === activeTocLink) { 294 return; 295 } 296 var tocLinks = tocElement.querySelectorAll("." + options.linkClass); 297 forEach.call(tocLinks, function(tocLink) { 298 tocLink.className = tocLink.className.split(SPACE_CHAR + options.activeLinkClass).join(""); 299 }); 300 var tocLis = tocElement.querySelectorAll("." + options.listItemClass); 301 forEach.call(tocLis, function(tocLi) { 302 tocLi.className = tocLi.className.split(SPACE_CHAR + options.activeListItemClass).join(""); 303 }); 304 if (activeTocLink && activeTocLink.className.indexOf(options.activeLinkClass) === -1) { 305 activeTocLink.className += SPACE_CHAR + options.activeLinkClass; 306 } 307 var li = activeTocLink && activeTocLink.parentNode; 308 if (li && li.className.indexOf(options.activeListItemClass) === -1) { 309 li.className += SPACE_CHAR + options.activeListItemClass; 310 } 311 var tocLists = tocElement.querySelectorAll("." + options.listClass + "." + options.collapsibleClass); 312 forEach.call(tocLists, function(list) { 313 if (list.className.indexOf(options.isCollapsedClass) === -1) { 314 list.className += SPACE_CHAR + options.isCollapsedClass; 315 } 316 }); 317 if (activeTocLink && activeTocLink.nextSibling && activeTocLink.nextSibling.className.indexOf(options.isCollapsedClass) !== -1) { 318 activeTocLink.nextSibling.className = activeTocLink.nextSibling.className.split(SPACE_CHAR + options.isCollapsedClass).join(""); 319 } 320 removeCollapsedFromParents(activeTocLink && activeTocLink.parentNode.parentNode); 321 } 322 } 323 function removeCollapsedFromParents(element) { 324 if (element && element.className.indexOf(options.collapsibleClass) !== -1 && element.className.indexOf(options.isCollapsedClass) !== -1) { 325 element.className = element.className.split(SPACE_CHAR + options.isCollapsedClass).join(""); 326 return removeCollapsedFromParents(element.parentNode.parentNode); 327 } 328 return element; 329 } 330 function disableTocAnimation(event) { 331 var target = event.target || event.srcElement; 332 if (typeof target.className !== "string" || target.className.indexOf(options.linkClass) === -1) { 333 return; 334 } 335 currentlyHighlighting = false; 336 } 337 function enableTocAnimation() { 338 currentlyHighlighting = true; 339 } 340 return { 341 enableTocAnimation, 342 disableTocAnimation, 343 render, 344 updateToc 345 }; 346}; 347 348 349/***/ }), 350 351/***/ 998: 352/***/ ((module) => { 353 354module.exports = { 355 // Where to render the table of contents. 356 tocSelector: ".js-toc", 357 // Where to grab the headings to build the table of contents. 358 contentSelector: ".js-toc-content", 359 // Which headings to grab inside of the contentSelector element. 360 headingSelector: "h1, h2, h3", 361 // Headings that match the ignoreSelector will be skipped. 362 ignoreSelector: ".js-toc-ignore", 363 // For headings inside relative or absolute positioned containers within content 364 hasInnerContainers: false, 365 // Main class to add to links. 366 linkClass: "toc-link", 367 // Extra classes to add to links. 368 extraLinkClasses: "", 369 // Class to add to active links, 370 // the link corresponding to the top most heading on the page. 371 activeLinkClass: "is-active-link", 372 // Main class to add to lists. 373 listClass: "toc-list", 374 // Extra classes to add to lists. 375 extraListClasses: "", 376 // Class that gets added when a list should be collapsed. 377 isCollapsedClass: "is-collapsed", 378 // Class that gets added when a list should be able 379 // to be collapsed but isn't necessarily collapsed. 380 collapsibleClass: "is-collapsible", 381 // Class to add to list items. 382 listItemClass: "toc-list-item", 383 // Class to add to active list items. 384 activeListItemClass: "is-active-li", 385 // How many heading levels should not be collapsed. 386 // For example, number 6 will show everything since 387 // there are only 6 heading levels and number 0 will collapse them all. 388 // The sections that are hidden will open 389 // and close as you scroll to headings within them. 390 collapseDepth: 0, 391 // Smooth scrolling enabled. 392 scrollSmooth: true, 393 // Smooth scroll duration. 394 scrollSmoothDuration: 420, 395 // Smooth scroll offset. 396 scrollSmoothOffset: 0, 397 // Callback for scroll end. 398 scrollEndCallback: function(e) { 399 }, 400 // Headings offset between the headings and the top of the document (this is meant for minor adjustments). 401 headingsOffset: 1, 402 // Timeout between events firing to make sure it's 403 // not too rapid (for performance reasons). 404 throttleTimeout: 50, 405 // Element to add the positionFixedClass to. 406 positionFixedSelector: null, 407 // Fixed position class to add to make sidebar fixed after scrolling 408 // down past the fixedSidebarOffset. 409 positionFixedClass: "is-position-fixed", 410 // fixedSidebarOffset can be any number but by default is set 411 // to auto which sets the fixedSidebarOffset to the sidebar 412 // element's offsetTop from the top of the document on init. 413 fixedSidebarOffset: "auto",
414 // includeHtml can be set to true to include the HTML markup from the 415 // heading node instead of just including the textContent. 416 includeHtml: false, 417 // includeTitleTags automatically sets the html title tag of the link 418 // to match the title. This can be useful for SEO purposes or 419 // when truncating titles. 420 includeTitleTags: false, 421 // onclick function to apply to all links in toc. will be called with 422 // the event as the first parameter, and this can be used to stop, 423 // propagation, prevent default or perform action 424 onClick: function(e) { 425 }, 426 // orderedList can be set to false to generate unordered lists (ul) 427 // instead of ordered lists (ol) 428 orderedList: true, 429 // If there is a fixed article scroll container, set to calculate titles' offset 430 scrollContainer: null, 431 // prevent ToC DOM rendering if it's already rendered by an external system 432 skipRendering: false, 433 // Optional callback to change heading labels. 434 // For example it can be used to cut down and put ellipses on multiline headings you deem too long. 435 // Called each time a heading is parsed. Expects a string and returns the modified label to display. 436 // Additionally, the attribute `data-heading-label` may be used on a heading to specify 437 // a shorter string to be used in the TOC. 438 // function (string) => string 439 headingLabelCallback: false, 440 // ignore headings that are hidden in DOM 441 ignoreHiddenElements: false, 442 // Optional callback to modify properties of parsed headings. 443 // The heading element is passed in node parameter and information parsed by default parser is provided in obj parameter. 444 // Function has to return the same or modified obj. 445 // The heading will be excluded from TOC if nothing is returned. 446 // function (object, HTMLElement) => object | void 447 headingObjectCallback: null, 448 // Set the base path, useful if you use a `base` tag in `head`. 449 basePath: "", 450 // Only takes affect when `tocSelector` is scrolling, 451 // keep the toc scroll position in sync with the content. 452 disableTocScrollSync: false, 453 // Offset for the toc scroll (top) position when scrolling the page. 454 // Only effective if `disableTocScrollSync` is false. 455 tocScrollOffset: 0 456}; 457 458 459/***/ }), 460 461/***/ 380: 462/***/ ((module, exports, __webpack_require__) => { 463 464var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(root, factory) { 465 if (true) { 466 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory(root)), 467 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 468 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 469 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 470 } else {} 471})(typeof __webpack_require__.g !== "undefined" ? __webpack_require__.g : window || __webpack_require__.g, function(root) { 472 "use strict"; 473 var defaultOptions = __webpack_require__(998); 474 var options = {}; 475 var tocbot = {}; 476 var BuildHtml = __webpack_require__(624); 477 var ParseContent = __webpack_require__(415); 478 var updateTocScroll = __webpack_require__(232); 479 var buildHtml; 480 var parseContent; 481 var supports = !!root && !!root.document && !!root.document.querySelector && !!root.addEventListener; 482 if (typeof window === "undefined" && !supports) { 483 return; 484 } 485 var headingsArray; 486 var hasOwnProperty = Object.prototype.hasOwnProperty; 487 function extend() { 488 var target = {}; 489 for (var i = 0; i < arguments.length; i++) { 490 var source = arguments[i]; 491 for (var key in source) { 492 if (hasOwnProperty.call(source, key)) { 493 target[key] = source[key]; 494 } 495 } 496 } 497 return target; 498 } 499 function throttle(fn, threshold, scope) { 500 threshold || (threshold = 250); 501 var last; 502 var deferTimer; 503 return function() { 504 var context = scope || this; 505 var now = +/* @__PURE__ */ new Date(); 506 var args = arguments; 507 if (last && now < last + threshold) { 508 clearTimeout(deferTimer); 509 deferTimer = setTimeout(function() { 510 last = now;
511 fn.apply(context, args); 512 }, threshold); 513 } else { 514 last = now; 515 fn.apply(context, args); 516 } 517 }; 518 } 519 function getContentElement(options2) { 520 try { 521 return options2.contentElement || document.querySelector(options2.contentSelector); 522 } catch (e) { 523 console.warn("Contents element not found: " + options2.contentSelector); 524 return null; 525 } 526 } 527 function getTocElement(options2) { 528 try { 529 return options2.tocElement || document.querySelector(options2.tocSelector); 530 } catch (e) { 531 console.warn("TOC element not found: " + options2.tocSelector); 532 return null; 533 } 534 } 535 tocbot.destroy = function() { 536 var tocElement = getTocElement(options); 537 if (tocElement === null) { 538 return; 539 } 540 if (!options.skipRendering) { 541 if (tocElement) { 542 tocElement.innerHTML = ""; 543 } 544 } 545 if (options.scrollContainer && document.querySelector(options.scrollContainer)) { 546 document.querySelector(options.scrollContainer).removeEventListener("scroll", this._scrollListener, false); 547 document.querySelector(options.scrollContainer).removeEventListener("resize", this._scrollListener, false); 548 if (buildHtml) { 549 document.querySelector(options.scrollContainer).removeEventListener("click", this._clickListener, false); 550 } 551 } else { 552 document.removeEventListener("scroll", this._scrollListener, false); 553 document.removeEventListener("resize", this._scrollListener, false); 554 if (buildHtml) { 555 document.removeEventListener("click", this._clickListener, false); 556 } 557 } 558 }; 559 tocbot.init = function(customOptions) { 560 if (!supports) { 561 return; 562 } 563 options = extend(defaultOptions, customOptions || {}); 564 this.options = options; 565 this.state = {}; 566 if (options.scrollSmooth) { 567 options.duration = options.scrollSmoothDuration; 568 options.offset = options.scrollSmoothOffset; 569 tocbot.scrollSmooth = (__webpack_require__(293).initSmoothScrolling)(options); 570 } 571 buildHtml = BuildHtml(options); 572 parseContent = ParseContent(options); 573 this._buildHtml = buildHtml; 574 this._parseContent = parseContent; 575 this._headingsArray = headingsArray; 576 tocbot.destroy(); 577 var contentElement = getContentElement(options); 578 if (contentElement === null) { 579 return; 580 } 581 var tocElement = getTocElement(options); 582 if (tocElement === null) { 583 return; 584 } 585 headingsArray = parseContent.selectHeadings(contentElement, options.headingSelector); 586 if (headingsArray === null) { 587 return; 588 } 589 var nestedHeadingsObj = parseContent.nestHeadingsArray(headingsArray); 590 var nestedHeadings = nestedHeadingsObj.nest; 591 if (!options.skipRendering) { 592 buildHtml.render(tocElement, nestedHeadings); 593 } 594 this._scrollListener = throttle(function(e) { 595 buildHtml.updateToc(headingsArray); 596 !options.disableTocScrollSync && updateTocScroll(options); 597 var isTop = e && e.target && e.target.scrollingElement && e.target.scrollingElement.scrollTop === 0; 598 if (e && (e.eventPhase === 0 || e.currentTarget === null) || isTop) { 599 buildHtml.updateToc(headingsArray); 600 if (options.scrollEndCallback) { 601 options.scrollEndCallback(e); 602 } 603 } 604 }, options.throttleTimeout); 605 this._scrollListener(); 606 if (options.scrollContainer && document.querySelector(options.scrollContainer)) { 607 document.querySelector(options.scrollContainer).addEventListener("scroll", this._scrollListener, false); 608 document.querySelector(options.scrollContainer).addEventListener("resize", this._scrollListener, false); 609 } else { 610 document.addEventListener("scroll", this._scrollListener, false); 611 document.addEventListener("resize", this._scrollListener, false); 612 } 613 var timeout = null; 614 this._clickListener = throttle(function(event) { 615 if (options.scrollSmooth) { 616 buildHtml.disableTocAnimation(event); 617 } 618 buildHtml.updateToc(headingsArray); 619 timeout && clearTimeout(timeout); 620 timeout = setTimeout(function() { 621 buildHtml.enableTocAnimation(); 622 }, options.scrollSmoothDuration); 623 }, options.throttleTimeout); 624 if (options.scrollContainer && document.querySelector(options.scrollContainer)) { 625 document.querySelector(options.scrollContainer).addEventListener("click", this._clickListener, false); 626 } else { 627 document.addEventListener("click", this._clickListener, false); 628 } 629 return this; 630 }; 631 tocbot.refresh = function(customOptions) { 632 tocbot.destroy(); 633 tocbot.init(customOptions || this.options); 634 }; 635 root.tocbot = tocbot; 636 return tocbot; 637}); 638 639 640/***/ }), 641 642/***/ 415: 643/***/ ((module) => { 644 645module.exports = function parseContent(options) { 646 var reduce = [].reduce; 647 function getLastItem(array) { 648 return array[array.length - 1]; 649 } 650 function getHeadingLevel(heading) { 651 return +heading.nodeName.toUpperCase().replace("H", ""); 652 } 653 function getHeadingObject(heading) { 654 if (!(heading instanceof window.HTMLElement)) return heading; 655 if (options.ignoreHiddenElements && (!heading.offsetHeight || !heading.offsetParent)) { 656 return null; 657 } 658 const headingLabel = heading.getAttribute("data-heading-label") || (
658options.headingLabelCallback ? String(options.headingLabelCallback(heading.textContent)) : heading.textContent.trim()); 659 var obj = { 660 id: heading.id, 661 children: [], 662 nodeName: heading.nodeName, 663 headingLevel: getHeadingLevel(heading), 664 textContent: headingLabel 665 }; 666 if (options.includeHtml) { 667 obj.childNodes = heading.childNodes; 668 } 669 if (options.headingObjectCallback) { 670 return options.headingObjectCallback(obj, heading); 671 } 672 return obj; 673 } 674 function addNode(node, nest) { 675 var obj = getHeadingObject(node); 676 var level = obj.headingLevel; 677 var array = nest; 678 var lastItem = getLastItem(array); 679 var lastItemLevel = lastItem ? lastItem.headingLevel : 0; 680 var counter = level - lastItemLevel; 681 while (counter > 0) { 682 lastItem = getLastItem(array); 683 if (lastItem && level === lastItem.headingLevel) { 684 break; 685 } else if (lastItem && lastItem.children !== void 0) { 686 array = lastItem.children; 687 } 688 counter--; 689 } 690 if (level >= options.collapseDepth) { 691 obj.isCollapsed = true; 692 } 693 array.push(obj); 694 return array; 695 } 696 function selectHeadings(contentElement, headingSelector) { 697 var selectors = headingSelector; 698 if (options.ignoreSelector) { 699 selectors = headingSelector.split(",").map(function mapSelectors(selector) { 700 return selector.trim() + ":not(" + options.ignoreSelector + ")"; 701 }); 702 } 703 try { 704 return contentElement.querySelectorAll(selectors); 705 } catch (e) { 706 console.warn("Headers not found with selector: " + selectors); 707 return null; 708 } 709 } 710 function nestHeadingsArray(headingsArray) { 711 return reduce.call(headingsArray, function reducer(prev, curr) { 712 var currentHeading = getHeadingObject(curr); 713 if (currentHeading) { 714 addNode(currentHeading, prev.nest); 715 } 716 return prev; 717 }, { 718 nest: [] 719 }); 720 } 721 return { 722 nestHeadingsArray, 723 selectHeadings 724 }; 725}; 726 727 728/***/ }), 729 730/***/ 293: 731/***/ ((__unused_webpack_module, exports) => { 732 733exports.initSmoothScrolling = initSmoothScrolling; 734function initSmoothScrolling(options) { 735 var duration = options.duration; 736 var offset = options.offset; 737 var pageUrl = location.hash ? stripHash(location.href) : location.href; 738 delegatedLinkHijacking(); 739 function delegatedLinkHijacking() { 740 document.body.addEventListener("click", onClick, false); 741 function onClick(e) { 742 if (!isInPageLink(e.target) || e.target.className.indexOf("no-smooth-scroll") > -1 || e.target.href.charAt(e.target.href.length - 2) === "#" && e.target.href.charAt(e.target.href.length - 1) === "!" || e.target.className.indexOf(options.linkClass) === -1) { 743 return; 744 } 745 jump(e.target.hash, { 746 duration, 747 offset, 748 callback: function() { 749 setFocus(e.target.hash); 750 } 751 }); 752 } 753 } 754 function isInPageLink(n) { 755 return n.tagName.toLowerCase() === "a" && (n.hash.length > 0 || n.href.charAt(n.href.length - 1) === "#") && (stripHash(n.href) === pageUrl || stripHash(n.href) + "#" === pageUrl); 756 } 757 function stripHash(url) { 758 return url.slice(0, url.lastIndexOf("#")); 759 } 760 function setFocus(hash) { 761 var element = document.getElementById(hash.substring(1)); 762 if (element) { 763 if (!/^(?:a|select|input|button|textarea)$/i.test(element.tagName)) { 764 element.tabIndex = -1; 765 } 766 element.focus(); 767 } 768 } 769} 770function jump(target, options) { 771 var start = window.pageYOffset; 772 var opt = { 773 duration: options.duration, 774 offset: options.offset || 0, 775 callback: options.callback, 776 easing: options.easing || easeInOutQuad 777 }; 778 var tgt = document.querySelector('[id="' + decodeURI(target).split("#").join("") + '"]') || document.querySelector('[id="' + target.split("#").join("") + '"]'); 779 var distance = typeof target === "string" ? opt.offset + (target ? tgt && tgt.getBoundingClientRect().top || 0 : -(document.documentElement.scrollTop || document.body.scrollTop)) : target; 780 var duration = typeof opt.duration === "function" ? opt.duration(distance) : opt.duration; 781 var timeStart; 782 var timeElapsed; 783 requestAnimationFrame(function(time) { 784 timeStart = time; 785 loop(time); 786 }); 787 function loop(time) { 788 timeElapsed = time - timeStart; 789 window.scrollTo(0, opt.easing(timeElapsed, start, distance, duration)); 790 if (timeElapsed < duration) { 791 requestAnimationFrame(loop); 792 } else { 793 end(); 794 } 795 } 796 function end() { 797 window.scrollTo(0, start + distance); 798 if (typeof opt.callback === "function") { 799 opt.callback(); 800 } 801 } 802 function easeInOutQuad(t, b, c, d) { 803 t /= d / 2; 804 if (t < 1) return c / 2 * t * t + b; 805 t--; 806 return -c / 2 * (t * (t - 2) - 1) + b; 807 } 808} 809 810 811/***/ }), 812 813/***/ 232: 814/***/ ((module) => { 815 816module.exports = function updateTocScroll(options) { 817 var toc = options.tocElement || document.querySelector(options.tocSelector); 818 if (toc && toc.scrollHeight > toc.clientHeight) { 819 var activeItem = toc.querySelector("." + options.activeListItemClass); 820 if (activeItem) { 821 toc.scrollTop = activeItem.offsetTop - options.tocScrollOffset; 822 } 823 } 824}; 825 826 827/***/ }), 828 829/***/ 102: 830/***/ ((__unused_webpack_module, __unused_webpack___webpack_exports__, __webpack_require__) => { 831 832"use strict"; 833 834// EXTERNAL MODULE: ./node_modules/tocbot/src/js/index.js 835var js = __webpack_require__(380); 836var js_default = /*#__PURE__*/__webpack_require__.n(js); 837// EXTERNAL MODULE: ./node_modules/debounce/index.js 838var debounce = __webpack_require__(267); 839var debounce_default = /*#__PURE__*/__webpack_require__.n(debounce); 840// EXTERNAL MODULE: ./node_modules/is-mobile/index.js 841var is_mobile = __webpack_require__(557); 842var is_mobile_default = /*#__PURE__*/__webpack_require__.n(is_mobile); 843;// ./src/main/sidebar.ts 844var __defProp = Object.defineProperty; 845var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; 846var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); 847 848 849 850const SidebarState = { 851 AUTO: "auto", 852 FIXED: "fixed", 853 RELATIVE: "relative" 854}; 855class Sidebar { 856 constructor(el, wrapper) { 857 __publicField(this, "el"); 858 __publicField(this, "wrapper"); 859 __publicField(this, "hidden"); 860 __publicField(this, "articleTopMargin"); 861 __publicField(this, "navbarHeight"); 862 __publicField(this, "state"); 863 __publicField(this, "isMobile"); 864 __publicField(this, "onScroll", () => { 865 this.state = SidebarState.AUTO; 866 if (!this.isMobile && window.scrollY > this.contentLocationInPage) { 867 this.state = SidebarState.FIXED; 868 } 869 if (!this.isMobile && window.scrollY > this.footerLocationFromDocument) { 870 this.state = SidebarState.RELATIVE; 871 } 872 this.computePosition(); 873 }); 874 this.el = el; 875 this.wrapper = wrapper; 876 this.hidden = true; 877 this.articleTopMargin = 20; 878 this.navbarHeight = 0; 879 this.state = SidebarState.AUTO; 880 const mediaQuery = window.matchMedia("(min-width: 768px)"); 881 this.isMobile = !mediaQuery.matches; 882 this.refresh(); 883 } 884 computePosition() { 885 if (this.state === SidebarState.AUTO) { 886 this.el.style.position = "initial"; 887 this.el.style.top = ""; 888 this.el.style.width = "auto"; 889 } else if (this.state === SidebarState.FIXED) { 890 this.el.style.position = "fixed"; 891 this.el.style.top = `${this.navbarHeight + this.articleTopMargin}px`; 892 const parentWidth = this.wrapper.clientWidth; 893 const computedStyle = window.getComputedStyle(this.wrapper); 894 const paddingLeft = parseFloat(computedStyle.getPropertyValue("padding-left")); 895 const paddingRight = parseFloat(computedStyle.getPropertyValue("padding-right")); 896 this.el.style.width = `${parentWidth - paddingLeft - paddingRight}px`; 897 } else if (this.state === SidebarState.RELATIVE) { 898 this.el.style.position = "relative"; 899 this.el.style.top = this.footerLocationFromDocument - this.contentLocationInPage + "px"; 900 this.el.style.width = "auto"; 901 } 902 } 903 /** 904 * Returns the top location of the footer with respect to the document root element, 905 * the value can't be cached because there are images and other layout things going on 906 * while scrolling 907 */ 908 get footerLocationFromDocument() { 909 const footer = document.querySelector("footer"); 910 if (!footer) return Infinity; 911 return footer.getBoundingClientRect().top + document.documentElement.scrollTop - window.innerHeight; 912 } 913 get contentLocationInPage() { 914 const content = document.querySelector("article[role=main]"); 915 if (!content) return Infinity; 916 return content.getBoundingClientRect().top + document.documentElement.scrollTop - this.articleTopMargin; 917 } 918 refresh() { 919 if (is_mobile_default()()) {
920 this.el.style.maxHeight = "initial"; 921 } else { 922 this.el.style.maxHeight = `calc(100vh - ${this.articleTopMargin * 2}px)`; 923 } 924 this.computePosition(); 925 } 926 // showIfHidden shows the sidebar if it's hidden 927 showIfHidden() { 928 if (this.hidden) { 929 this.wrapper.style.opacity = "0.8"; 930 this.hidden = false; 931 } 932 } 933 hideIfShown() { 934 if (!this.hidden) { 935 this.wrapper.style.opacity = "0"; 936 this.hidden = true; 937 } 938 } 939} 940function initializeSidebar(sidebarWrapper, sidebarContent) { 941 if (!sidebarWrapper || !sidebarContent) { 942 console.warn("Attempted to initialize a sidebar where the elements were not found!"); 943 return; 944 } 945 const sidebar = new Sidebar(sidebarContent, sidebarWrapper); 946 const onResize = debounce_default()(function onResize2() { 947 sidebar.refresh(); 948 }, 250); 949 window.addEventListener("resize", onResize); 950 window.addEventListener("orientationchange", onResize); 951 if (!is_mobile_default()()) { 952 window.addEventListener("scroll", function() { 953 sidebar.onScroll(); 954 }); 955 let lastMouseIn = 0; 956 let isMouseEnter = false; 957 sidebar.wrapper.addEventListener("mouseleave", function() { 958 isMouseEnter = false; 959 lastMouseIn = Date.now(); 960 }); 961 sidebar.wrapper.addEventListener("mouseenter", function() { 962 isMouseEnter = true; 963 sidebar.showIfHidden(); 964 }); 965 setInterval(() => { 966 if (Date.now() - lastMouseIn > 2e3 && !isMouseEnter) { 967 sidebar.hideIfShown(); 968 } 969 }, 100); 970 } else { 971 sidebar.showIfHidden(); 972 } 973 sidebar.onScroll(); 974} 975function initialize() { 976 const sitemap = document.querySelector(".my-sitemap"); 977 const sitemapWrapper = document.querySelector(".my-sitemap-wrapper"); 978 initializeSidebar(sitemapWrapper, sitemap); 979 const toc = document.querySelector(".toc"); 980 const tocWrapper = document.querySelector(".toc-wrapper"); 981 initializeSidebar(tocWrapper, toc); 982 let activeLinkClass = "is-active-link"; 983 if (is_mobile_default()()) { 984 activeLinkClass = "foo"; 985 } 986 js_default().init({ 987 tocSelector: ".toc", 988 contentSelector: "article[role=main]", 989 headingSelector: "h1,h2,h3,h4,h5,h6", 990 collapseDepth: 6, 991 throttleTimeout: 200, 992 activeLinkClass 993 }); 994} 995function sidebarsMain() { 996 if (document.readyState === "loading") { 997 document.addEventListener("DOMContentLoaded", initialize); 998 } else { 999 initialize(); 1000 } 1001} 1002 1003;// ./src/main/sitemap.ts 1004function sitemap_initialize() { 1005 const sitemap = document.querySelector("#sitemap-tree"); 1006 if (!sitemap) return; 1007 const current = Array.from(sitemap.querySelectorAll("a")).find((link) => link.pathname === window.location.pathname); 1008 if (current) { 1009 const activeItem = current.closest("li"); 1010 if (activeItem) activeItem.classList.add("is-active"); 1011 } 1012} 1013function sitemapMain() { 1014 if (document.readyState === "loading") { 1015 document.addEventListener("DOMContentLoaded", sitemap_initialize); 1016 } else { 1017 sitemap_initialize(); 1018 } 1019} 1020 1021;// ./src/main/search-shortcut.ts 1022function searchShortcutMain() { 1023 window.addEventListener("keydown", (event) => { 1024 if ((event.metaKey || event.ctrlKey) && event.key === "k") { 1025 const target = event.target; 1026 if (target && (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable)) { 1027 return; 1028 } 1029 event.preventDefault(); 1030 window.location.href = "/notes/?search=true"; 1031 } 1032 }); 1033} 1034 1035;// ./src/main/lazy-load.ts 1036const Lozad = __webpack_require__(285); 1037function lazyLoadMain() { 1038 new Lozad(".lazy-load").observe(); 1039} 1040 1041;// ./src/main/equation-preview.ts 1042var __async = (__this, __arguments, generator) => { 1043 return new Promise((resolve, reject) => { 1044 var fulfilled = (value) => { 1045 try { 1046 step(generator.next(value)); 1047 } catch (e) { 1048 reject(e); 1049 } 1050 }; 1051 var rejected = (value) => { 1052 try { 1053 step(generator.throw(value)); 1054 } catch (e) { 1055 reject(e); 1056 } 1057 }; 1058 var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); 1059 step((generator = generator.apply(__this, __arguments)).next()); 1060 }); 1061}; 1062function run() { 1063 const tooltip = document.createElement("div"); 1064 const container = document.querySelector("article[role=main]"); 1065 tooltip.style.display = "none"; 1066 tooltip.style.backgroundColor = "var(--grey-dark)"; 1067 tooltip.classList.add("mathjax-tooltip", "tw-rounded", "tw-mx-auto", "tw-absolute"); 1068 container.appendChild(tooltip); 1069 function getTarget(ev) { 1070 return ev.currentTarget.closest("a"); 1071 } 1072 function onMouseOver(ev) { 1073 var _a; 1074 const href = getTarget(ev); 1075 if (!href) return; 1076 let target = decodeURIComponent(href.hash || ((_a = href == null ? void 0 : href.href) == null ? void 0 : _a.baseVal)); 1077 target = target.replace(/:/g, "\\:"); 1078 const number = document.querySelector(target); 1079 const targetContainer = number.closest(".content"); 1080 const equation = number.closest(".MathJax");
1081 Object.assign(tooltip.style, { 1082 top: `${href.closest(".MathJax").offsetTop + 50}px`, 1083 width: `${targetContainer.getBoundingClientRect().width}px`, 1084 display: "block" 1085 }); 1086 tooltip.appendChild(equation.cloneNode(true)); 1087 } 1088 function onMouseOut(ev) { 1089 const href = getTarget(ev); 1090 if (!href) return; 1091 tooltip.innerHTML = ""; 1092 Object.assign(tooltip.style, { display: "none" }); 1093 } 1094 function start() { 1095 return __async(this, null, function* () { 1096 var _a, _b; 1097 if (!((_b = (_a = window.MathJax) == null ? void 0 : _a.startup) == null ? void 0 : _b.promise)) return; 1098 yield window.MathJax.startup.promise; 1099 Array.from(document.querySelectorAll(".MathJax_ref")).forEach((el) => { 1100 el.addEventListener("mouseover", onMouseOver); 1101 el.addEventListener("mouseout", onMouseOut); 1102 }); 1103 }); 1104 } 1105 if (document.readyState === "complete" || document.readyState === "interactive") { 1106 start(); 1107 } else { 1108 document.addEventListener("DOMContentLoaded", start); 1109 } 1110} 1111function equationPreviewMain() { 1112 const container = document.querySelector("article[role=main]"); 1113 if (container) run(); 1114} 1115 1116;// ./src/main/footnotes-preview.ts 1117var footnotes_preview_async = (__this, __arguments, generator) => { 1118 return new Promise((resolve, reject) => { 1119 var fulfilled = (value) => { 1120 try { 1121 step(generator.next(value)); 1122 } catch (e) { 1123 reject(e); 1124 } 1125 }; 1126 var rejected = (value) => { 1127 try { 1128 step(generator.throw(value)); 1129 } catch (e) { 1130 reject(e); 1131 } 1132 }; 1133 var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); 1134 step((generator = generator.apply(__this, __arguments)).next()); 1135 }); 1136}; 1137function footnotes_preview_run() { 1138 const tooltip = document.createElement("div"); 1139 const container = document.querySelector("article[role=main]"); 1140 tooltip.style.display = "none"; 1141 tooltip.style.backgroundColor = "var(--grey-dark)"; 1142 tooltip.classList.add( 1143 "footnotes", 1144 "footnotes-tooltip", 1145 "tw-rounded", 1146 "tw-mx-auto", 1147 "tw-absolute", 1148 "tw-p-3" 1149 ); 1150 container.appendChild(tooltip); 1151 function getTarget(ev) { 1152 return ev.currentTarget.closest("a"); 1153 } 1154 function onMouseOver(ev) { 1155 const a = getTarget(ev); 1156 if (!a) return; 1157 let target = decodeURIComponent(a.hash); 1158 target = target.replace(/:/g, "\\:"); 1159 const footnote = document.querySelector(target); 1160 const targetContainer = footnote.closest(".content"); 1161 console.log(footnote); 1162 Object.assign(tooltip.style, { 1163 // Get the position of the parent <sup> element instead of the <a> element. 1164 // The reason is that <sup> sets position: relative making offsetTop not work 1165 // as expected on <a>. 1166 top: `${a.parentElement.offsetTop + 50}px`, 1167 width: `${targetContainer.getBoundingClientRect().width}px`, 1168 display: "block" 1169 }); 1170 tooltip.appendChild(footnote.cloneNode(true)); 1171 } 1172 function onMouseOut(ev) { 1173 const href = getTarget(ev); 1174 if (!href) return; 1175 tooltip.innerHTML = ""; 1176 Object.assign(tooltip.style, { display: "none" }); 1177 } 1178 function start() { 1179 return footnotes_preview_async(this, null, function* () { 1180 Array.from(document.querySelectorAll(".footnote-ref")).forEach((el) => { 1181 el.addEventListener("mouseover", onMouseOver); 1182 el.addEventListener("mouseout", onMouseOut); 1183 }); 1184 }); 1185 } 1186 if (document.readyState === "complete" || document.readyState === "interactive") { 1187 start(); 1188 } else { 1189 document.addEventListener("DOMContentLoaded", start); 1190 } 1191} 1192function main() { 1193 const container = document.querySelector("article[role=main]"); 1194 if (container) footnotes_preview_run(); 1195} 1196function footnotesPreviewMain() { 1197 main(); 1198} 1199 1200;// ./src/main/math-terms.ts 1201var math_terms_defProp = Object.defineProperty; 1202var __defProps = Object.defineProperties; 1203var __getOwnPropDescs = Object.getOwnPropertyDescriptors; 1204var __getOwnPropSymbols = Object.getOwnPropertySymbols; 1205var __hasOwnProp = Object.prototype.hasOwnProperty; 1206var __propIsEnum = Object.prototype.propertyIsEnumerable; 1207var math_terms_defNormalProp = (obj, key, value) => key in obj ? math_terms_defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; 1208var __spreadValues = (a, b) => { 1209 for (var prop in b || (b = {})) 1210 if (__hasOwnProp.call(b, prop)) 1211 math_terms_defNormalProp(a, prop, b[prop]); 1212 if (__getOwnPropSymbols) 1213 for (var prop of __getOwnPropSymbols(b)) { 1214 if (__propIsEnum.call(b, prop)) 1215 math_terms_defNormalProp(a, prop, b[prop]); 1216 } 1217 return a; 1218}; 1219var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); 1220const SYSTEMS_TERMS = { 1221 lambda: { 1222 symbol: "\\lambda", 1223 name: "Arrival Rate", 1224 category: "System Capacity", 1225 unit: "req/s", 1226 summary: "The rate at which incoming requests arrive at the system per unit time.", 1227 formulas: [ 1228 "\\lambda = \\frac{N}{\\Delta t}", 1229 "N = \\lambda \\cdot W \\quad \\text{(Little's Law)}", 1230 "\\rho = \\frac{\\lambda}{c \\cdot \\mu} \\quad \\text{(Utilization)}" 1231 ], 1232 insight: "In open-loop systems (real internet users), arrivals occur independently of server responsiveness. When demand \u03BB approaches cluster capacity c\xB7\u03BC, queue wait times explode." 1233 }, 1234 mu: { 1235 symbol: "\\mu", 1236 name: "Service Rate", 1237 category: "System Capacity", 1238 unit: "req/s/core", 1239 summary: "The maximum processing speed of a single worker core or thread when continuously busy.", 1240 formulas: [ 1241 "\\mu = \\frac{1}{S}", 1242 "\\text{Cluster Capacity} = c \\cdot \\mu" 1243 ], 1244 insight: "Service rate is determined by hardware performance and code execution efficie
1244ncy. It represents the reciprocal of active service time S." 1245 }, 1246 rho: { 1247 symbol: "\\rho", 1248 name: "Resource Utilization", 1249 category: "Queuing Theory", 1250 unit: "% (or 0.0 \u2013 1.0)", 1251 summary: "The fraction of total processing capacity currently in active use across all available worker cores.", 1252 formulas: [ 1253 "\\rho = \\frac{\\lambda}{c \\cdot \\mu} = \\frac{\\sum T_{\\text{busy}}}{c \\cdot \\Delta t}", 1254 "\\text{Headroom} = 1 - \\rho" 1255 ], 1256 insight: "Due to stochastic request clumping, systems enter an exponential latency knee around \u03C1 \u2248 75%. Sizing steady-state workloads above 80% leaves insufficient headroom to absorb traffic spikes." 1257 }, 1258 W: { 1259 symbol: "W", 1260 name: "Server Response Time", 1261 category: "Latency Metric", 1262 unit: "seconds / ms", 1263 summary: "The total duration a request spends inside the server boundary from queue arrival until completion.", 1264 formulas: [ 1265 "W = W_q + S", 1266 "W = \\frac{S}{1 - \\rho} = \\frac{1}{\\mu - \\lambda} \\quad (M/M/1)" 1267 ], 1268 insight: "Total server time is the sum of queue wait time (W_q) and active computation (S). As utilization \u03C1 approaches 100%, W is dominated almost entirely by queue wait time." 1269 }, 1270 S: { 1271 symbol: "S", 1272 name: "Service Time", 1273 category: "Latency Metric", 1274 unit: "seconds / ms", 1275 summary: "The time a request actively executes on a worker core once it exits the waiting queue.", 1276 formulas: [ 1277 "S = \\frac{1}{\\mu}", 1278 "W = W_q + S" 1279 ], 1280 insight: "Service time represents the uncontended latency floor (observed when \u03C1 \u2192 0). Optimizing algorithms or hardware lowers S, directly increasing processing capacity \u03BC." 1281 }, 1282 V: { 1283 symbol: "V", 1284 name: "Visit Count", 1285 category: "System Capacity", 1286 unit: "visits / request", 1287 summary: "The number of times a request visits a subsystem during its execution.", 1288 formulas: [ 1289 "D = V \\cdot S", 1290 "S_{\\text{request}} \\approx \\sum_k V_k S_k" 1291 ], 1292 insight: "A subsystem can dominate demand through repeated visits even when each visit is fast. Reducing redundant passes, transfers, retries, or routing hops lowers V and can outperform a local speedup that only lowers S." 1293 }, 1294 service_center: { 1295 symbol: "\\text{SC}", 1296 name: "Service Center", 1297 category: "Queuing Theory", 1298 unit: "workers / resource pool", 1299 summary: "A modeled resource pool that performs active work for queued jobs, such as a CPU worker pool, GPU, database connection pool, or router.", 1300 formulas: [ 1301 "\\rho_k = \\frac{\\lambda D_k}{m_k}", 1302 "\\lambda_{\\text{sat}} \\leq \\min_k \\frac{m_k}{D_k}" 1303 ], 1304 insight: "A service center can contain one worker or many equivalent workers. Its capacity, service demand, and queue determine how much work the system can sustain before this resource becomes the bottleneck." 1305 }, 1306 M_weights: { 1307 symbol: "M_{\\text{weights}}", 1308 name: "Model Weight Memory", 1309 category: "System Capacity", 1310 unit: "bytes / GB", 1311 summary: "The memory required to store a model\u2019s parameters before accounting for the KV cache and runtime buffers.", 1312 formulas: [ 1313 "M_{\\text{weights}} \\approx \\frac{P \\cdot b}{8}", 1314 "M_{\\text{weights}} \\approx 2P \\text{ bytes} \\quad (b = 16)" 1315 ], 1316 insight: "Weight memory determines whether a model can fit on one accelerator. If it does not, the model must be partitioned or its weights must use a lower-precision format." 1317 }, 1318 L: { 1319 symbol: "L", 1320 name: "In-Flight Requests (Concurrency)", 1321 category: "System Capacity", 1322 unit: "requests", 1323 summary: "The average total number of requests currently inside the system (both waiting in queue and actively executing).", 1324 formulas: [ 1325 "L = \\lambda \\cdot W \\quad \\text{(Little's Law)}", 1326 "L = \\frac{\\rho}{1 - \\rho} \\quad (M/M/1)" 1327 ], 1328 insight: "Little's Law guarantees that concurrency is strictly the product of throughput and latency. If latency doubles at constant traffic, in-flight concurrency doubles." 1329 }, 1330 c: { 1331 symbol: "c", 1332 name: "Parallel Worker Count", 1333 category: "System Capacity", 1334 unit: "cores / servers", 1335 summary: "The number of independent parallel servers, worker processes, or CPU cores processing requests from the queue.", 1336 formulas: [ 1337 "\\text{Total Capacity} = c \\cdot \\mu", 1338 "\\rho = \\frac{\\lambda}{c \\cdot \\mu}" 1339 ], 1340 insight: "Under a shared queue (M/M/c), pooling capacity across c workers reduces average queue wait time roughly by a factor of 1/c compared to isolated single-worker queues." 1341 } 1342}; 1343const QUEUING_TERMS = __spreadProps(__spreadValues({}, SYSTEMS_TERMS), { 1344 Ca: { 1345 symbol: "C_a", 1346 name: "Arrival Variability", 1347 category: "Statistical Metric", 1348 unit: "dimensionless", 1349 summary: "The coefficient of variation of inter-arrival times, measuring how unevenly requests reach a service center.", 1350 formulas: [ 1351 "C_a = \\frac{\\sigma_A}{\\bar{A}}" 1352 ], 1353 insight: "A larger C_a means burstier arrivals. At the same average arrival rate, burstier traffic creates more queue wait than regular traffic." 1354 }, 1355 Cs: { 1356 symbol: "C_s", 1357 name: "Service-Time Variability", 1358 category: "Statistical Metric", 1359 unit: "dimensionless", 1360 summary: "The coefficient of variation of service times, measuring how unevenly a service center handles individual jobs.", 1361 formulas: [ 1362 "C_s = \\frac{\\sigma_S}{\\bar{S}}" 1363 ], 1364 insight: "A larger C_s means more variable execution times. Long jobs mixed with short jobs increase queue wait through head-of-line blocking and make tail latency less predictable." 1365 }, 1366 W_q: { 1367 symbol: "W_q", 1368 name: "Queue Wait Time", 1369 category: "Queuing Theory", 1370 unit: "seconds / ms", 1371 summary: "The duration a request spends stalled in the FIFO queue waiting for a worker core to become free before execution begins.", 1372 formulas: [ 1373 "W_q = \\frac{\\rho \\cdot S}{1 - \\rho} = \\frac{\\rho}{\\mu(1 - \\rho)} \\quad (M/M/1)", 1374 "W_q = \\frac{\\rho \\cdot S}{1 - \\rho} \\left(\\frac{1 + C_v^2}{2}\\right) \\quad (M/G/1 \\text{ P-K})", 1375 "W_q = \\frac{C(c, a) \\cdot S}{c(1 - \\rho)} \\quad (M/M/c \\text{ Erlang C})" 1376 ], 1377 insight: "Queue wait is 100% idle latency overhead where zero useful compute is performed. It doubles between 50% \u2192 75% utilization, and explodes 10x past 90% utilization." 1378 }, 1379 L_q: { 1380 symbol: "L_q", 1381 name: "Queue Depth (Queue Length)", 1382 category: "Queuing Theory", 1383 unit: "requests", 1384 summary: "The average number of requests waiting in the queue buffer before worker dispatch.", 1385 formulas: [ 1386 "L_q = \\lambda \\cdot W_q \\quad \\text{(Little's Law)}", 1387 "L_q = \\frac{\\rho^2}{1 - \\rho} \\quad (M/M/1)" 1388 ], 1389 insight: "A non-zero queue depth signals that incoming bursts are arriving faster than instantaneous worker availability. Monitoring L_q provides early warning before full saturation." 1390 }, 1391 Cv: { 1392 symbol: "C_v", 1393 name: "Coefficient of Variation", 1394 category: "Statistical Metric", 1395 unit: "dimensionless", 1396 summary: "The normalized measure of service time variance, defined as standard deviation divided by mean service time.", 1397 formulas: [ 1398 "C_v = \\frac{\\sigma_S}{\\mu_S}", 1399 "\\text{P-K Multiplier} = \\frac{1 + C_v^2}{2}" 1400 ], 1401 insight: "High variance (bimodal queries, long-tail payloads) creates Head-of-Line blocking. Deterministic execution (Cv = 0) cuts queue wait in half (0.5x), while high variance (Cv = 3) inflates queue wait 5x." 1402 } 1403}); 1404const LLM_TERMS = { 1405 N_batch: { 1406 symbol: "N_{\\text{batch}}", 1407 name: "Active Batch Size", 1408 category: "LLM Inference", 1409 unit: "sequences / serving iteration", 1410 summary: "The number of active request sequences processed together in one serving iteration.", 1411 formulas: [ 1412 "N_{\\text{batch}} = \\text{active sequences in one iteration}", 1413 "\\text{Aggregate TPS} \\approx \\frac{N_{\\text{batch}}}{\\text{TPOT}}" 1414 ], 1415 insight: "A larger active batch can improve accelerator utilization and aggregate throughput, but it consumes more KV-cache memory and can increase per-request token latency. Continuous batching changes N_batch as requests arrive, finish, or are paused." 1416 }, 1417 TTFT: { 1418 symbol: "\\text{TTFT}", 1419 name: "Time to First Token", 1420 category: "LLM Inference", 1421 unit: "ms", 1422 summary: "The duration from when a user sends a prompt to when the server streams back the very first output token.", 1423 formulas: [ 1424 "\\text{TTFT} = 2 \\cdot t_{\\text{net}} + t_{\\text{queue}} + t_{\\text{prefill}}", 1425 "\\text{Prefill FLOPs} \\approx 2 \\cdot P \\cdot \\text{ISL}" 1426 ], 1427 insight: "Determined by the prompt prefill phase. Because the GPU computes all input tokens in parallel, prefill is heavily Compute-Bound, saturating tensor cores at near 100% duty cycle." 1428 }, 1429 TPOT: { 1430 symbol: "\\text{TPOT}", 1431 name: "Time Per Output Token", 1432 category: "LLM Inference", 1433 unit: "ms/token", 1434 summary: "The generation latency for each subsequent token during autoregressive decode (often perceived as streaming speed).", 1435 formulas: [ 1436 "\\text{TPOT} = \\frac{\\text{Decode Phase Latency}}{\\text{Output Tokens}}", 1437 "\\text{Streaming Speed} = \\frac{1}{\\text{TPOT}} \\quad (\\text{tok/s/stream})" 1438 ], 1439 insight: "Decode is Memory-Bandwidth-Bound. For every single generated token, the GPU must stream all parameter weights (~2 bytes per parameter in FP16) from HBM into SRAM." 1440 }, 1441 TPS: { 1442 symbol: "\\text{TPS}", 1443 name: "Tokens Per Second", 1444 category: "LLM Inference", 1445 unit: "tok/s", 1446 summary: "The aggregate output throughput generated across all concurrent client streams by the serving cluster.", 1447 formulas: [ 1448 "\\text{TPS} = \\frac{\\sum \\text{Output Tokens}}{\\Delta t} = \\text{Batch Size} \\times \\frac{1}{\\text{TPOT}}" 1449 ], 1450 insight: "Increasing batch size boosts TPS and GPU memory efficie
1450ncy, but increases per-request TPOT and queue wait, representing the primary multi-objective Pareto trade-off." 1451 }, 1452 ITL: { 1453 symbol: "\\text{ITL}", 1454 name: "Inter-Token Latency", 1455 category: "LLM Inference", 1456 unit: "ms", 1457 summary: "The time delay between consecutive streamed tokens delivered to the client application.", 1458 formulas: [ 1459 "\\text{ITL} \\approx \\text{TPOT} + t_{\\text{chunk}}" 1460 ], 1461 insight: "High ITL variance causes perceptible stuttering in interactive chatbots and voice agents. Consistent ITL requires isolating chunked prefills from ongoing decode iterations." 1462 }, 1463 NTTFT: { 1464 symbol: "\\text{NTTFT}", 1465 name: "Normalized TTFT", 1466 category: "LLM Inference", 1467 unit: "ms/input_token", 1468 summary: "Time to First Token divided by the input prompt length (ISL), providing a normalized metric across variable prompt sizes.", 1469 formulas: [ 1470 "\\text{NTTFT} = \\frac{\\text{TTFT}}{\\text{Input Sequence Length (ISL)}}" 1471 ], 1472 insight: "Allows fair performance comparisons between short queries (e.g. 50 tokens) and long-context document summarization (e.g. 8,000 tokens)." 1473 }, 1474 sigma_noise: { 1475 symbol: "\\vec{\\sigma}_{\\text{noise}}", 1476 name: "Noise Tolerance Band Vector", 1477 category: "LLM Inference", 1478 unit: "% per objective", 1479 summary: "A vector of measurement noise thresholds defining the statistical indifference corridor for each serving objective.", 1480 formulas: [ 1481 "\\forall i, \\quad f_i(\\mathbf{x}_A) \\le f_i(\\mathbf{x}_B) \\cdot (1 + \\sigma_{\\text{noise}, i})", 1482 "\\sigma_{\\text{noise}, i} \\approx C_{v, i} \\quad \\text{(Empirical Benchmark Variance)}" 1483 ], 1484 insight: "In production GPU serving, benchmark noise (thermal throttling, network jitter, variable prompt lengths) creates false Pareto wins. Fluctuations within \xB1\u03C3_noise are treated as statistical ties rather than meaningful improvements." 1485 }, 1486 delta_min: { 1487 symbol: "\\vec{\\delta}_{\\text{min}}", 1488 name: "Minimum Improvement Threshold Vector", 1489 category: "LLM Inference", 1490 unit: "% per objective", 1491 summary: "A vector of minimum percentage improvements required in at least one objective to claim genuine engineering dominance.", 1492 formulas: [ 1493 "\\exists j, \\quad f_j(\\mathbf{x}_A) \\le f_j(\\mathbf{x}_B) \\cdot (1 - \\delta_{\\text{min}, j})", 1494 "\\Delta f_j = \\frac{f_j(\\mathbf{x}) - f_j(\\mathbf{x}_0)}{f_j(\\mathbf{x}_0)} \\ge \\delta_{\\text{min}, j}" 1495 ], 1496 insight: "Enforces a practical significance hurdle (e.g. \u2265 3% latency reduction or +5% throughput gain). Prevents micro-optimizations from polluting the frontier when they pass raw mathematical dominance without delivering real-world value." 1497 } 1498}; 1499const GRAPHICS_TERMS = { 1500 S: { 1501 symbol: "\\mathbf{S}", 1502 name: "Scale Matrix", 1503 category: "Computer Graphics", 1504 summary: "A diagonal 4\xD74 affine matrix scaling geometry along local coordinate axes by factors $(s_x, s_y, s_z)$ at the origin.", 1505 formulas: [ 1506 "\\mathbf{S}(s_x, s_y, s_z) = \\begin{bmatrix} s_x & 0 & 0 & 0 \\\\ 0 & s_y & 0 & 0 \\\\ 0 & 0 & s_z & 0 \\\\ 0 & 0 & 0 & 1 \\end{bmatrix}" 1507 ], 1508 insight: "Scaling must occur at the local origin before translation. If an object is translated away first, scaling expands its distance from the origin rather than resizing in place." 1509 }, 1510 R: { 1511 symbol: "\\mathbf{R}", 1512 name: "Rotation Matrix", 1513 category: "Computer Graphics", 1514 summary: "An orthonormal 4\xD74 matrix rotating 3D coordinates around a coordinate axis or arbitrary vector by angle $\\theta$.", 1515 formulas: [ 1516 "\\mathbf{R}_y(\\theta) = \\begin{bmatrix} \\cos\\theta & 0 & \\sin\\theta & 0 \\\\ 0 & 1 & 0 & 0 \\\\ -\\sin\\theta & 0 & \\cos\\theta & 0 \\\\ 0 & 0 & 0 & 1 \\end{bmatrix}" 1517 ], 1518 insight: "Rotation matrices are orthogonal: their inverse is simply their transpose ($\\mathbf{R}^{-1} = \\mathbf{R}^T$), preserving lengths and angles." 1519 }, 1520 T: { 1521 symbol: "\\mathbf{T}", 1522 name: "Translation Matrix", 1523 category: "Computer Graphics", 1524 summary: "An affine 4\xD74 matrix displacing 3D coordinates by position offset vector $(t_x, t_y, t_z)$.", 1525 formulas: [ 1526 "\\mathbf{T}(t_x, t_y, t_z) = \\begin{bmatrix} 1 & 0 & 0 & t_x \\\\ 0 & 1 & 0 & t_y \\\\ 0 & 0 & 1 & t_z \\\\ 0 & 0 & 0 & 1 \\end{bmatrix}" 1527 ], 1528 insight: "Translation requires 4D homogeneous coordinates ($w = 1$). It displaces points while leaving directional vectors ($w = 0$) invariant." 1529 }, 1530 TRS: { 1531 symbol: "\\mathbf{T} \\mathbf{R} \\mathbf{S}", 1532 name: "Matrix Function Composition", 1533 category: "Computer Graphics", 1534 summary: "Composing affine transformations acts identically to nested function application: $(\\mathbf{T} \\circ \\mathbf{R} \\circ \\mathbf{S})(\\mathbf{v}) = \\mathbf{T}(\\mathbf{R}(\\mathbf{S}(\\mathbf{v}
1534)))$.", 1535 formulas: [ 1536 "\\mathbf{v}' = \\mathbf{T} \\cdot \\mathbf{R} \\cdot \\mathbf{S} \\cdot \\mathbf{v} = \\mathbf{T}(\\mathbf{R}(\\mathbf{S}(\\mathbf{v})))" 1537 ], 1538 insight: "Matrices evaluate right-to-left because matrix-vector multiplication is functional application: the innermost transformation applies first." 1539 }, 1540 TR: { 1541 symbol: "\\mathbf{T} \\mathbf{R}", 1542 name: "Rotation Followed by Translation", 1543 category: "Computer Graphics", 1544 summary: "Transforms a vector by rotating first in place around the origin, then displacing by translation vector $\\mathbf{T}$.", 1545 formulas: [ 1546 "\\mathbf{T} \\mathbf{R} = \\begin{bmatrix} \\mathbf{R}_{3 \\times 3} & \\mathbf{T}_{3 \\times 1} \\\\ \\mathbf{0}_{1 \\times 3} & 1 \\end{bmatrix}", 1547 "\\mathbf{v}' = \\mathbf{T} \\mathbf{R} \\mathbf{v} = \\mathbf{R} \\mathbf{v} + \\mathbf{T}_{3 \\times 1}" 1548 ], 1549 insight: "Rotates coordinates at the local origin before translating into position, keeping the rotation centered on the object." 1550 }, 1551 RT: { 1552 symbol: "\\mathbf{R} \\mathbf{T}", 1553 name: "Translation Followed by Rotation", 1554 category: "Computer Graphics", 1555 summary: "Transforms a vector by translating first, then rotating around the global origin.", 1556 formulas: [ 1557 "\\mathbf{R} \\mathbf{T} = \\begin{bmatrix} \\mathbf{R}_{3 \\times 3} & \\mathbf{R}_{3 \\times 3} \\mathbf{T}_{3 \\times 1} \\\\ \\mathbf{0}_{1 \\times 3} & 1 \\end{bmatrix}", 1558 "\\mathbf{v}' = \\mathbf{R} \\mathbf{T} \\mathbf{v} = \\mathbf{R} \\mathbf{v} + \\mathbf{R}\\mathbf{T}_{3 \\times 1}" 1559 ], 1560 insight: "Translating first displaces the object away from the origin; the subsequent rotation rotates both the geometry and its displacement vector in an orbit around $(0, 0, 0)$." 1561 }, 1562 M_proj: { 1563 symbol: "\\mathbf{M}_{\\text{proj}}", 1564 name: "Projection Matrix", 1565 category: "Computer Graphics", 1566 summary: "Transforms 3D view-space coordinates into homogeneous clip space for perspective or orthographic projection.", 1567 formulas: [ 1568 "\\mathbf{v}_{\\text{clip}} = \\mathbf{M}_{\\text{proj}} \\mathbf{v}_{\\text{view}}", 1569 "\\mathbf{v}_{\\text{ndc}} = \\mathbf{v}_{\\text{clip}} / w_{\\text{clip}}" 1570 ], 1571 insight: "Maps the 3D view frustum into the canonical unit cube. For perspective projection, z-depth is stored in the w-component to enable the perspective divide." 1572 }, 1573 M_view: { 1574 symbol: "\\mathbf{M}_{\\text{view} \\leftarrow \\text{world}}", 1575 name: "View Transform Matrix", 1576 category: "Computer Graphics", 1577 summary: "Transforms world-space coordinates into camera (view/eye) space using the camera orientation and position.", 1578 formulas: [ 1579 "\\mathbf{v}_{\\text{view}} = \\mathbf{M}_{\\text{view} \\leftarrow \\text{world}} \\mathbf{v}_{\\text{world}} = \\mathbf{R}^T \\mathbf{T}^{-1} \\mathbf{v}_{\\text{world}}" 1580 ], 1581 insight: "Moving the camera forward is mathematically equivalent to translating the entire 3D world backward by the inverse camera transform matrix." 1582 }, 1583 M_model: { 1584 symbol: "\\mathbf{M}_{\\text{world} \\leftarrow \\text{object}}", 1585 name: "Model Transform Matrix", 1586 category: "Computer Graphics", 1587 summary: "Transforms coordinates from local object space into the global world coordinate frame.", 1588 formulas: [ 1589 "\\mathbf{v}_{\\text{world}} = \\mathbf{M}_{\\text{world} \\leftarrow \\text{object}} \\mathbf{v}_{\\text{object}}", 1590 "\\mathbf{M}_{\\text{world} \\leftarrow \\text{object}} = \\mathbf{T} \\mathbf{R} \\mathbf{S}" 1591 ], 1592 insight: "Composed in TRS order: geometry is first scaled at the local origin, rotated in place, and finally translated into world coordinates." 1593 }, 1594 ndc: { 1595 symbol: "\\mathbf{v}_{\\text{ndc}}", 1596 name: "Normalized Device Coordinates", 1597 category: "Computer Graphics", 1598 summary: "The canonical coordinate volume spanning [-1, 1] in x, y, and z after perspective division by w.", 1599 formulas: [ 1600 "\\mathbf{v}_{\\text{ndc}} = [x_{\\text{clip}}/w, y_{\\text{clip}}/w, z_{\\text{clip}}/w]^T" 1601 ], 1602 insight: "Clipping occurs before the divide by w to avoid divi
1602ding by zero when primitives cross behind the near plane ($w \\leq 0$)." 1603 }, 1604 quaternion: { 1605 symbol: "\\mathbf{q}", 1606 name: "Unit Quaternion", 1607 category: "Computer Graphics", 1608 summary: "A 4D hypercomplex number used to represent smooth 3D rotations without gimbal lock.", 1609 formulas: [ 1610 "\\mathbf{q} = \\cos(\\theta/2) + \\mathbf{u} \\sin(\\theta/2) = [w, x, y, z]", 1611 "\\mathbf{v}' = \\mathbf{q} \\mathbf{v} \\mathbf{q}^*" 1612 ], 1613 insight: "Spherical Linear Interpolation (SLERP) on unit quaternions guarantees constant angular velocity along the shortest geodesic arc on the 4D hypersphere." 1614 }, 1615 homogeneous: { 1616 symbol: "(x, y, z, w)", 1617 name: "Homogeneous Coordinates", 1618 category: "Computer Graphics", 1619 summary: "A 4-component projective coordinate system enabling affine translations via 4x4 matrix multiplication.", 1620 formulas: [ 1621 "\\mathbf{v} = (x, y, z, 1)^T \\implies \\mathbf{T} \\mathbf{v} = (x + t_x, y + t_y, z + t_z, 1)^T" 1622 ], 1623 insight: "Points have w = 1 (affected by translations), while directional vectors have w = 0 (invariant under translation)." 1624 } 1625}; 1626const CALCULUS_TERMS = { 1627 derivative: { 1628 symbol: "f'(x)", 1629 name: "Derivative", 1630 category: "Calculus", 1631 summary: "The instantaneous rate of change of a function with respect to its independent variable.", 1632 formulas: [ 1633 "f'(x) = \\lim_{h \\to 0} \\frac{f(x + h) - f(x)}{h}", 1634 "\\frac{df}{dx} = \\frac{d}{dx} f(x)" 1635 ], 1636 insight: "Geometrically represents the slope of the tangent line to the curve at point x, indicating local velocity and gradient." 1637 }, 1638 integral: { 1639 symbol: "\\int_a^b f(x) \\, dx", 1640 name: "Definite Integral", 1641 category: "Calculus", 1642 summary: "The continuous accumulation or signed area between the curve f(x) and the x-axis from x = a to x = b.", 1643 formulas: [ 1644 "\\int_a^b f(x) \\, dx = F(b) - F(a) \\quad \\text{(FTC)}", 1645 "\\int f(x) \\, dx = F(x) + C" 1646 ], 1647 insight: "Integration acts as the continuous sum of infinitely many infinitesimal slices of width dx, reversing differentiation." 1648 }, 1649 taylor: { 1650 symbol: "T_n(x)", 1651 name: "Taylor Polynomial", 1652 category: "Calculus", 1653 summary: "An approximation of a differentiable function around a point a using a power series of its derivatives.", 1654 formulas: [ 1655 "T_n(x) = \\sum_{k=0}^n \\frac{f^{(k)}(a)}{k!} (x - a)^k" 1656 ], 1657 insight: "Provides fast, bounded polynomial approximations used in numerical physics, shader approximation, and mathematical libraries." 1658 } 1659}; 1660const CATEGORY_MAP = { 1661 queuing: QUEUING_TERMS, 1662 systems: SYSTEMS_TERMS, 1663 llm: LLM_TERMS, 1664 graphics: GRAPHICS_TERMS, 1665 calculus: CALCULUS_TERMS 1666}; 1667function getTermsForCategories(categories) { 1668 if (categories === "all") { 1669 return __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({}, SYSTEMS_TERMS), QUEUING_TERMS), LLM_TERMS), GRAPHICS_TERMS), CALCULUS_TERMS); 1670 } 1671 const merged = {}; 1672 for (const cat of categories) { 1673 if (CATEGORY_MAP[cat]) { 1674 Object.assign(merged, CATEGORY_MAP[cat]); 1675 } 1676 } 1677 return merged; 1678} 1679function normalizeTermKey(raw, activeTerms) { 1680 if (!raw) return null; 1681 const cleaned = raw.trim().replace(/\\text\{([^}]+)\}/g, "$1").replace(/[${\\}\s]/g, ""); 1682 const noUnderscore = cleaned.replace(/_/g, ""); 1683 if (activeTerms[cleaned]) return cleaned; 1684 if (activeTerms[noUnderscore]) return noUnderscore; 1685 const aliasMap = { 1686 \u03BB: "lambda", 1687 lambda: "lambda", 1688 \u03BC: "mu", 1689 mu: "mu", 1690 \u03C1: "rho", 1691 rho: "rho", 1692 W: "W", 1693 wq: "W_q", 1694 W_q: "W_q", 1695 Wq: "W_q", 1696 S: "S", 1697 L: "L", 1698 lq: "L_q", 1699 L_q: "L_q", 1700 Lq: "L_q", 1701 c: "c", 1702 cv: "Cv", 1703 Cv: "Cv", 1704 C_v: "Cv", 1705 ttft: "TTFT", 1706 TTFT: "TTFT", 1707 tpot: "TPOT", 1708 TPOT: "TPOT", 1709 tps: "TPS", 1710 TPS: "TPS", 1711 itl: "ITL", 1712 ITL: "ITL", 1713 nttft: "NTTFT", 1714 NTTFT: "NTTFT", 1715 sigma_noise: "sigma_noise", 1716 sigmanoise: "sigma_noise", 1717 sigmatextnoise: "sigma_noise", 1718 vecsigma: "sigma_noise", 1719 vecsigmanoise: "sigma_noise", 1720 vecsigmatextnoise: "sigma_noise", 1721 sigma: "sigma_noise", 1722 \u03C3: "sigma_noise", 1723 \u03C3_noise: "sigma_noise", 1724 "vec(\u03C3)": "sigma_noise", 1725 delta_min: "delta_min", 1726 deltamin: "delta_min", 1727 deltatextmin: "delta_min", 1728 vecdelta: "delta_min", 1729 vecdeltamin: "delta_min", 1730 vecdeltatextmin: "delta_min", 1731 delta: "delta_min", 1732 \u03B4: "delta_min", 1733 \u03B4_min: "delta_min", 1734 "vec(\u03B4)": "delta_min", 1735 m_proj: "M_proj", 1736 M_proj: "M_proj", 1737 Mproj: "M_proj", 1738 m_view: "M_view", 1739 M_view: "M_view", 1740 Mview: "M_view", 1741 m_model: "M_model", 1742 M_model: "M_model", 1743 Mmodel: "M_model", 1744 ndc: "ndc", 1745 quaternion: "quaternion", 1746 q: "quaternion", 1747 homogeneous: "homogeneous", 1748 R: "R", 1749 R_y: "R", 1750 Ry: "R", 1751 R_z: "R", 1752 Rz: "R", 1753 T: "T", 1754 TRS: "TRS", 1755 trs: "TRS", 1756 TR: "TR", 1757 tr: "TR", 1758 RT: "RT", 1759 rt: "RT", 1760 derivative: "derivative", 1761 integral: "integral", 1762 taylor: "taylor" 1763 }; 1764 const alias = aliasMap[cleaned] || aliasMap[noUnderscore]; 1765 if (alias && activeTerms[alias]) { 1766 return alias; 1767 } 1768 if (activeTerms.M_model && cleaned.includes("world") && cleaned.includes("object")) { 1769 return "M_model"; 1770 } 1771 if (activeTerms.M_view && cleaned.includes("view") && cleaned.includes("world")) { 1772 return "M_view"; 1773 } 1774 return null; 1775} 1776 1777;// ./src/main/math-term-preview.ts 1778 1779function formatMathSnippet(tex) {
1780 if (typeof window !== "undefined" && window.katex && typeof window.katex.renderToString === "function") { 1781 try { 1782 return window.katex.renderToString(tex, { displayMode: false, throwOnError: false }); 1783 } catch (e) { 1784 return `<code>${tex}</code>`; 1785 } 1786 } 1787 return `<code>${tex}</code>`; 1788} 1789function renderTextWithMath(str) { 1790 if (!str) return ""; 1791 return str.replace(/\$([^$]+)\$/g, (_, math) => formatMathSnippet(math)); 1792} 1793function buildPopoverHTML(term) { 1794 const renderedSymbol = formatMathSnippet(term.symbol); 1795 const unitBadge = term.unit ? `<div class="math-popover-unit-group"><span class="math-popover-unit-label">Unit:</span><span class="math-popover-unit">${term.unit}</span></div>` : ""; 1796 const formulaRows = (term.formulas || []).map((f) => `<div class="math-popover-formula-line">${formatMathSnippet(f)}</div>`).join(""); 1797 const formulasSection = formulaRows ? `<div class="math-popover-formulas-block"> 1798 <div class="math-popover-section-label">Key Formulas</div> 1799 <div class="math-popover-formulas">${formulaRows}</div> 1800 </div>` : ""; 1801 const insightSection = term.insight ? `<div class="math-popover-insight"><strong class="math-popover-insight-tag">Insight</strong> ${renderTextWithMath(term.insight)}</div>` : ""; 1802 return ` 1803 <div class="math-popover-header"> 1804 <div class="math-popover-title-row"> 1805 <span class="math-popover-symbol">${renderedSymbol}</span> 1806 <span class="math-popover-name">${term.name}</span> 1807 </div> 1808 <div class="math-popover-meta-row"> 1809 <span class="math-popover-category">${term.category}</span> 1810 ${unitBadge} 1811 </div> 1812 </div> 1813 <div class="math-popover-summary">${renderTextWithMath(term.summary)}</div> 1814 ${formulasSection} 1815 ${insightSection} 1816 `; 1817} 1818function initMathTermPreview(containerSelector = "article[role=main]") { 1819 const container = document.querySelector(containerSelector); 1820 if (!container) return; 1821 const section = container.closest("section") || document.querySelector("section[data-libraries]"); 1822 let activeCategories = null; 1823 if (section) { 1824 const rawMathTerms = section.getAttribute("data-math-terms"); 1825 const rawLibraries = section.getAttribute("data-libraries"); 1826 if (rawMathTerms && rawMathTerms !== '""' && rawMathTerms !== "null") { 1827 try { 1828 const parsed = JSON.parse(rawMathTerms); 1829 if (Array.isArray(parsed)) { 1830 activeCategories = parsed; 1831 } else if (parsed === true || parsed === "all") { 1832 activeCategories = "all"; 1833 } 1834 } catch (e) { 1835 if (rawMathTerms.includes("queuing") || rawMathTerms.includes("systems") || rawMathTerms.includes("llm") || rawMathTerms.includes("graphics") || rawMathTerms.includes("calculus")) { 1836 activeCategories = rawMathTerms.split(",").map((s) => s.trim()); 1837 } 1838 } 1839 } else if (rawLibraries && rawLibraries.includes("math-terms")) { 1840 activeCategories = "all"; 1841 } 1842 } 1843 if (!activeCategories || Array.isArray(activeCategories) && activeCategories.length === 0) { 1844 return; 1845 } 1846 const activeTerms = getTermsForCategories(activeCategories); 1847 if (Object.keys(activeTerms).length === 0) return; 1848 let popover = document.querySelector(".math-popover-card"); 1849 if (!popover) { 1850 popover = document.createElement("div"); 1851 popover.className = "math-popover-card"; 1852 popover.style.display = "none"; 1853 document.body.appendChild(popover); 1854 } 1855 let showTimer = null; 1856 let hideTimer = null; 1857 function showCard(target, termKey) { 1858 clearTimeout(hideTimer); 1859 const term = activeTerms[termKey]; 1860 if (!term) return; 1861 popover.innerHTML = buildPopoverHTML(term); 1862 popover.style.display = "block"; 1863 const targetRect = target.getBoundingClientRect(); 1864 const popoverRect = popover.getBoundingClientRect(); 1865 const scrollY = window.pageYOffset || document.documentElement.scrollTop; 1866 const scrollX = window.pageXOffset || document.documentElement.scrollLeft; 1867 let top = targetRect.bottom + scrollY + 8; 1868 if (targetRect.bottom + popoverRect.height + 20 > window.innerHeight && targetRect.top > popoverRect.height + 20) { 1869 top = targetRect.top + scrollY - popoverRect.height - 8; 1870 } 1871 let left = targetRect.left + scrollX - 20; 1872 const maxLeft = scrollX + window.innerWidth - popoverRect.width - 16; 1873 if (left > maxLeft) { 1874 left = maxLeft; 1875 } 1876 if (left < scrollX + 16) { 1877 left = scrollX + 16; 1878 } 1879 popover.style.top = `${top}px`; 1880 popover.style.left = `${left}px`; 1881 requestAnimationFrame(() => { 1882 popover.classList.add("is-visible"); 1883 }); 1884 } 1885 function hideCard() { 1886 clearTimeout(showTimer); 1887 hideTimer = setTimeout(() => { 1888 popover.classList.remove("is-visible"); 1889 setTimeout(() => { 1890 if (!popover.classList.contains("is-visible")) { 1891 popover.style.display = "none"; 1892 } 1893 }, 160); 1894 }, 120); 1895 } 1896 popover.addEventListener("mouseenter", () => { 1897 clearTimeout(hideTimer); 1898 }); 1899 popover.addEventListener("mouseleave", () => { 1900 hideCard(); 1901 }); 1902 function bindElement(el, key) { 1903 if (el.hasAttribute("data-term-bound")) return; 1904 el.setAttribute("data-term-bound", "true"); 1905 el.setAttribute("data-term-active", "true"); 1906 el.addEventListener("mouseenter", () => { 1907 clearTimeout(hideTimer); 1908 showTimer = setTimeout(() => showCard(el, key), 100); 1909 }); 1910 el.addEventListener("mouseleave", hideCard); 1911 } 1912 function scanKaTeXInsideEquation(katexEl) { 1913 const htmlContainer = katexEl.querySelector(".katex-html"); 1914 if (!htmlContainer) return; 1915 const supsubElements = htmlContainer.querySelectorAll(".msupsub");
1916 supsubElements.forEach((subEl) => { 1917 const prevEl = subEl.previousElementSibling; 1918 if (!prevEl) return; 1919 const baseText = (prevEl.textContent || "").trim(); 1920 const subText = (subEl.textContent || "").trim(); 1921 let compositeKey = null; 1922 if (baseText === "W" && subText.includes("q")) { 1923 compositeKey = "W_q"; 1924 } else if (baseText === "L" && subText.includes("q")) { 1925 compositeKey = "L_q"; 1926 } else if (baseText === "C" && subText.includes("v")) { 1927 compositeKey = "Cv"; 1928 } else if (baseText === "C" && subText.includes("a")) { 1929 compositeKey = "Ca"; 1930 } else if (baseText === "C" && subText.includes("s")) { 1931 compositeKey = "Cs"; 1932 } else if (baseText === "R" && (subText.includes("y") || subText.includes("z") || subText.includes("x") || subText.includes("3"))) { 1933 compositeKey = "R"; 1934 } else if (baseText === "T" && (subText.includes("3") || subText.includes("1") || subText.includes("cam"))) { 1935 compositeKey = "T"; 1936 } else if (baseText === "S" && subText.includes("3")) { 1937 compositeKey = "S"; 1938 } else if (baseText === "M" && subText.includes("proj")) { 1939 compositeKey = "M_proj"; 1940 } else if (baseText === "M" && subText.includes("weights")) { 1941 compositeKey = "M_weights"; 1942 } else if (baseText === "M" && (subText.includes("view") || subText.includes("view") && subText.includes("world"))) { 1943 compositeKey = "M_view"; 1944 } else if (baseText === "M" && (subText.includes("model") || subText.includes("world") && subText.includes("object"))) { 1945 compositeKey = "M_model"; 1946 } else if ((baseText.includes("\u03C3") || baseText.includes("sigma")) && (subText.includes("noise") || subText.includes("tol"))) { 1947 compositeKey = "sigma_noise"; 1948 } else if ((baseText.includes("\u03B4") || baseText.includes("delta")) && (subText.includes("min") || subText.includes("req"))) { 1949 compositeKey = "delta_min"; 1950 } 1951 if (compositeKey && activeTerms[compositeKey]) { 1952 bindElement(prevEl, compositeKey); 1953 bindElement(subEl, compositeKey); 1954 } 1955 }); 1956 const symbolElements = htmlContainer.querySelectorAll(".mord, .mord.mathnormal, .mord.text"); 1957 symbolElements.forEach((symEl) => { 1958 if (symEl.hasAttribute("data-term-bound")) return; 1959 if (symEl.querySelector(".mord")) return; 1960 const text = (symEl.textContent || "").trim(); 1961 if (!text || text.length > 10) return; 1962 const key = normalizeTermKey(text, activeTerms); 1963 if (key) { 1964 bindElement(symEl, key); 1965 } 1966 }); 1967 } 1968 function scanTerms() { 1969 const explicitTerms = container.querySelectorAll("[data-term], [data-math-term]"); 1970 explicitTerms.forEach((el) => { 1971 const raw = el.getAttribute("data-term") || el.getAttribute("data-math-term") || ""; 1972 const key = normalizeTermKey(raw, activeTerms); 1973 if (key) { 1974 bindElement(el, key); 1975 } 1976 }); 1977 const katexElements = container.querySelectorAll(".katex"); 1978 katexElements.forEach((el) => { 1979 const annotation = el.querySelector("annotation"); 1980 const rawTex = annotation ? (annotation.textContent || "").trim() : (el.textContent || "").trim(); 1981 const isolatedKey = normalizeTermKey(rawTex, activeTerms); 1982 if (isolatedKey) { 1983 bindElement(el, isolatedKey); 1984 } else { 1985 scanKaTeXInsideEquation(el); 1986 } 1987 }); 1988 } 1989 scanTerms(); 1990 setTimeout(scanTerms, 150); 1991 setTimeout(scanTerms, 600); 1992 const observer = new MutationObserver(() => { 1993 scanTerms(); 1994 }); 1995 observer.observe(container, { childList: true, subtree: true }); 1996 document.addEventListener("click", (e) => { 1997 const clicked = e.target; 1998 if (!clicked.closest(".math-popover-card") && !clicked.closest("[data-term-active]")) { 1999 popover.classList.remove("is-visible"); 2000 popover.style.display = "none"; 2001 } 2002 }); 2003} 2004function mathTermPreviewMain() { 2005 if (typeof document === "undefined") return; 2006 if (document.readyState === "loading") { 2007 document.addEventListener("DOMContentLoaded", () => initMathTermPreview()); 2008 } else { 2009 initMathTermPreview(); 2010 } 2011} 2012 2013;// ./src/main/index.ts 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023sidebarsMain(); 2024searchShortcutMain(); 2025sitemapMain(); 2026lazyLoadMain(); 2027equationPreviewMain(); 2028footnotesPreviewMain(); 2029mathTermPreviewMain(); 2030 2031 2032/***/ }) 2033 2034}, 2035/******/ __webpack_require__ => { // webpackRuntimeModules 2036/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId)) 2037/******/ var __webpack_exports__ = (__webpack_exec__(102));
2038/******/ main = __webpack_exports__; 2039/******/ } 2040]);
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.