{
  "version": 3,
  "sources": ["/cdn/shop/t/22/compiled_assets/scripts.js?%5B314%2Cf%28roofY%28314%29-6%29%5D%3A%5BantX%2C%28antBase+arrY%29%2F2%5D%2Ca.windowpass=%5B346%2CentryY%5D%2Cgnd%3D"],
  "sourcesContent": ["(function() {\n  var __sections__ = {};\n  (function() {\n    for(var i = 0, s = document.getElementById('sections-script').getAttribute('data-sections').split(','); i < s.length; i++)\n      __sections__[s[i]] = true;\n    })();\n    (function() {\n  if (!__sections__[\"header\"]) return;\n  try {\n    \n  class StickyHeader extends HTMLElement {\n    constructor() {\n      super();\n      this.setHeaderHeight = this.setHeaderHeight.bind(this);\n    }\n\n    connectedCallback() {\n      this.header = document.querySelector('.section-header');\n      this.mobileMediaQuery = window.matchMedia('(max-width: 990px)');\n      this.headerIsAlwaysSticky =\n        this.getAttribute('data-sticky-type') === 'always' ||\n        this.getAttribute('data-sticky-type') === 'reduce-logo-size';\n      this.headerBounds = {};\n\n      this.setHeaderHeight();\n\n      this.mobileMediaQuery.addEventListener('change', this.setHeaderHeight);\n\n      if (this.headerIsAlwaysSticky) {\n        this.header.classList.add('shopify-section-header-sticky');\n      }\n\n      this.currentScrollTop = 0;\n      this.preventReveal = false;\n      this.predictiveSearches = this.querySelectorAll('predictive-search');\n\n      this.onScrollHandler = this.onScroll.bind(this);\n      this.hideHeaderOnScrollUp = () => (this.preventReveal = true);\n\n      this.addEventListener('preventHeaderReveal', this.hideHeaderOnScrollUp);\n      window.addEventListener('scroll', this.onScrollHandler, false);\n\n      this.createObserver();\n    }\n\n    setHeaderHeight() {\n      document.documentElement.style.setProperty('--header-height', `${this.header.offsetHeight}px`);\n    }\n\n    disconnectedCallback() {\n      this.mobileMediaQuery.removeEventListener('change', this.setHeaderHeight);\n      this.removeEventListener('preventHeaderReveal', this.hideHeaderOnScrollUp);\n      window.removeEventListener('scroll', this.onScrollHandler);\n    }\n\n    createObserver() {\n      let observer = new IntersectionObserver((entries, observer) => {\n        this.headerBounds = entries[0].intersectionRect;\n        observer.disconnect();\n      });\n\n      observer.observe(this.header);\n    }\n\n    onScroll() {\n      const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n\n      if ([...this.predictiveSearches].some((predictiveSearch) => predictiveSearch.isOpen)) return;\n\n      if (scrollTop > this.currentScrollTop && scrollTop > this.headerBounds.bottom) {\n        this.header.classList.add('scrolled-past-header');\n        if (this.preventHide) return;\n        requestAnimationFrame(this.hide.bind(this));\n      } else if (scrollTop < this.currentScrollTop && scrollTop > this.headerBounds.bottom) {\n        this.header.classList.add('scrolled-past-header');\n        if (!this.preventReveal) {\n          requestAnimationFrame(this.reveal.bind(this));\n        } else {\n          window.clearTimeout(this.isScrolling);\n\n          this.isScrolling = setTimeout(() => {\n            this.preventReveal = false;\n          }, 66);\n\n          requestAnimationFrame(this.hide.bind(this));\n        }\n      } else if (scrollTop <= this.headerBounds.top) {\n        this.header.classList.remove('scrolled-past-header');\n        requestAnimationFrame(this.reset.bind(this));\n      }\n\n      this.currentScrollTop = scrollTop;\n    }\n\n    hide() {\n      if (this.headerIsAlwaysSticky) return;\n      this.header.classList.add('shopify-section-header-hidden', 'shopify-section-header-sticky');\n      this.closeMenuDisclosure();\n      this.closeSearchModal();\n    }\n\n    reveal() {\n      if (this.headerIsAlwaysSticky) return;\n      this.header.classList.add('shopify-section-header-sticky', 'animate');\n      this.header.classList.remove('shopify-section-header-hidden');\n    }\n\n    reset() {\n      if (this.headerIsAlwaysSticky) return;\n      this.header.classList.remove('shopify-section-header-hidden', 'shopify-section-header-sticky', 'animate');\n    }\n\n    closeMenuDisclosure() {\n      this.disclosures = this.disclosures || this.header.querySelectorAll('header-menu');\n      this.disclosures.forEach((disclosure) => disclosure.close());\n    }\n\n    closeSearchModal() {\n      this.searchModals = this.searchModals || this.header.querySelectorAll('details-modal');\n      this.searchModals.forEach((searchModal) => searchModal.close(false));\n    }\n  }\n\n  // The account `open` event is composed but does not bubble, so listen during capture.\n  // Anchor the dialog to the bottom of the account button itself. The header group can be\n  // much taller than the button's row (for example, a top-left logo pushes the menu to a\n  // second row), so anchoring to the section bottom drops the dialog too low.\n  document.addEventListener(\n    'open',\n    (event) => {\n      if (!(event.target instanceof HTMLElement) || !event.target.matches('shopify-account')) return;\n\n      const bottom = Math.max(0, Math.round(event.target.getBoundingClientRect().bottom));\n      event.target.style.setProperty('--account-dialog-top', `${bottom}px`);\n    },\n    true\n  );\n\n  customElements.define('sticky-header', StickyHeader);\n\n  } catch(e) { console.error(e); }\n})();\n\n(function() {\n  if (!__sections__[\"mn-setup-planner\"] && !Shopify.designMode) return;\n  try {\n    \n/*\n * Mapping Network Setup Planner: French text for the French store (/fr).\n *\n * The English text stays in the code and is the lookup key: t('Feedline loss')\n * returns the French from src/fr.json when the page is French, else the English.\n * {name} placeholders are filled from vars. The build inlines the table.\n */\n(function (global) {\n  'use strict';\n\n  var FR = {\"Where will the antenna go?\":\"O\u00F9 ira l'antenne\u00A0?\",\"Indoors at a window\":\"\u00C0 l'int\u00E9rieur, pr\u00E8s d'une fen\u00EAtre\",\"Attic\":\"Grenier\",\"Outside wall\":\"Mur ext\u00E9rieur\",\"Roof, mast or tower\":\"Toit, m\u00E2t ou tour\",\"What's around it?\":\"Qu'y a-t-il autour\u00A0?\",\"Dense city\":\"Centre-ville dense\",\"Suburbs or small town\":\"Banlieue ou petite ville\",\"Open countryside\":\"Campagne d\u00E9gag\u00E9e\",\"Hills or valleys\":\"Collines ou vall\u00E9es\",\"I only need to cover one direction (for example a town or farm across a valley)\":\"Je n'ai besoin de couvrir qu'une direction (par exemple un village ou une ferme de l'autre c\u00F4t\u00E9 d'une vall\u00E9e)\",\"How high is the antenna?\":\"\u00C0 quelle hauteur est l'antenne\u00A0?\",\"Height above the ground. A storey is about 3 m.\":\"Hauteur au-dessus du sol. Un \u00E9tage mesure environ 3 m.\",\"Where will the hotspot sit?\":\"O\u00F9 sera le hotspot\u00A0?\",\"Inside, with a cable out to the antenna\":\"\u00C0 l'int\u00E9rieur, avec un c\u00E2ble jusqu'\u00E0 l'antenne\",\"Outside in an enclosure beside the antenna\":\"\u00C0 l'ext\u00E9rieur, dans un bo\u00EEtier \u00E0 c\u00F4t\u00E9 de l'antenne\",\"Which hotspot do you have?\":\"Quel hotspot avez-vous\u00A0?\",\"RAK Hotspot Miner or RAK7244 gateway\":\"RAK Hotspot Miner ou passerelle RAK7244\",\"Something else\":\"Autre\",\"How will the cable get inside?\":\"Comment le c\u00E2ble entrera-t-il\u00A0?\",\"Through a wall or existing hole\":\"Par un mur ou un trou existant\",\"Under a closed window (no drilling)\":\"Sous une fen\u00EAtre ferm\u00E9e (sans per\u00E7age)\",\"Cable length from hotspot to antenna\":\"Longueur du c\u00E2ble entre le hotspot et l'antenne\",\"Want to help build the Helium IoT network?\":\"Vous voulez contribuer au r\u00E9seau IdO Helium\u00A0?\",\"A hotspot gives LoRaWAN coverage to sensors and trackers around you and can join the Helium network. We make no promise of rewards or earnings: they depend on your location and the network, and can be zero. See real coverage at world.helium.com.\":\"Un hotspot offre une couverture LoRaWAN aux capteurs et traceurs autour de vous et peut se joindre au r\u00E9seau Helium. Nous ne faisons aucune promesse de r\u00E9compenses ni de gains\u00A0: ils d\u00E9pendent de votre emplacement et du r\u00E9seau, et peuvent \u00EAtre nuls. Consultez la couverture r\u00E9elle sur world.helium.com.\",\"I already have a hotspot\":\"J'ai d\u00E9j\u00E0 un hotspot\",\"Yes, add a hotspot to my setup\":\"Oui, ajoutez un hotspot \u00E0 mon installation\",\"Calculated figures\":\"Chiffres calcul\u00E9s\",\"Antenna gain (manufacturer spec)\":\"Gain de l'antenne (sp\u00E9cification du fabricant)\",\"Feedline loss\":\"Perte de la ligne\",\"Line-of-sight horizon\":\"Horizon en visibilit\u00E9 directe\",\"The horizon is the furthest an antenna at {h} m can see a device 1.5 m off the ground over perfectly smooth terrain. It is a geometric limit, not a coverage estimate. Buildings, trees and terrain usually limit real-world range to much less.\":\"L'horizon est la distance maximale \u00E0 laquelle une antenne \u00E0 {h} m peut \u00AB\u00A0voir\u00A0\u00BB un appareil situ\u00E9 \u00E0 1,5 m du sol, sur un terrain parfaitement lisse. C'est une limite g\u00E9om\u00E9trique, pas une estimation de couverture. Les b\u00E2timents, les arbres et le relief limitent habituellement la port\u00E9e r\u00E9elle \u00E0 beaucoup moins.\",\"*Plus {unspecified}.\":\"*Plus {unspecified}.\",\"the enclosure's included pigtail (length not specified by the manufacturer)\":\"le c\u00E2ble amorce (pigtail) inclus avec le bo\u00EEtier (longueur non pr\u00E9cis\u00E9e par le fabricant)\",\"Your parts\":\"Vos pi\u00E8ces\",\"numbers match the drawing\":\"les num\u00E9ros correspondent au sch\u00E9ma\",\"Include {product}\":\"Inclure {product}\",\"Browse our antennas and cables for this setup.\":\"Parcourez nos antennes et nos c\u00E2bles pour cette installation.\",\"Untick anything you already own.\":\"D\u00E9cochez ce que vous poss\u00E9dez d\u00E9j\u00E0.\",\"Add selected to cart\":\"Ajouter la s\u00E9lection au panier\",\"Copy a link to this plan\":\"Copier le lien de ce plan\",\"Send it to your installer, or save it for later.\":\"Envoyez-le \u00E0 votre installateur, ou gardez-le pour plus tard.\",\"How it connects and how we calculate\":\"Raccordements et m\u00E9thode de calcul\",\"Share of transmit power reaching the antenna\":\"Part de la puissance d'\u00E9mission qui atteint l'antenne\",\"(before the pigtail)\":\"(avant le c\u00E2ble amorce)\",\"Cable loss is the manufacturer's typical attenuation at 900 MHz (Times Microwave LMR-400 12.8 dB/100 m, LMR-200 32.6 dB/100 m, LMR-100A 74.9 dB/100 m), multiplied by the cable length. The arrestor uses its rated loss (RAKwireless \u22640.2 dB, Laird under 0.25 dB at 1000 MHz). Each connection or adaptor gets an allowance of 0.1 dB.\":\"La perte de c\u00E2ble correspond \u00E0 l'att\u00E9nuation typique du fabricant \u00E0 900 MHz (Times Microwave LMR-400 12,8 dB/100 m, LMR-200 32,6 dB/100 m, LMR-100A 74,9 dB/100 m), multipli\u00E9e par la longueur du c\u00E2ble. Le parafoudre utilise sa perte nominale (RAKwireless \u2264 0,2 dB, Laird moins de 0,25 dB \u00E0 1000 MHz). Chaque connexion ou adaptateur re\u00E7oit une marge de 0,1 dB.\",\"The line-of-sight horizon is d = 4.12 \u00D7 (\u221Ah antenna + \u221A1.5) km, the standard radio-horizon formula with 4/3-Earth refraction.\":\"L'horizon en visibilit\u00E9 directe est d = 4,12 \u00D7 (\u221Ah antenne + \u221A1,5) km, la formule standard de l'horizon radio avec une r\u00E9fraction de 4/3 de la Terre.\",\"Link copied. Anyone who opens it sees this plan.\":\"Lien copi\u00E9. Toute personne qui l'ouvre verra ce plan.\",\"Adding to cart\u2026\":\"Ajout au panier\u2026\",\"Added {n} item(s) to your cart.\":\"{n} article(s) ajout\u00E9(s) \u00E0 votre panier.\",\"Could not add to cart\":\"Impossible d'ajouter au panier\",\"{error}. Please try again, or add the items from their product pages.\":\"{error}. Veuillez r\u00E9essayer, ou ajoutez les articles depuis leur page produit.\",\"A flat-panel directional antenna concentrates its signal in one direction, so at a window it sends most of it outside toward a town, farm or valley instead of into the room. Face it out through the glass.\":\"Une antenne directionnelle plate concentre son signal dans une seule direction\u00A0: pr\u00E8s d'une fen\u00EAtre, elle l'envoie surtout vers l'ext\u00E9rieur, vers un village, une ferme ou une vall\u00E9e, plut\u00F4t que dans la pi\u00E8ce. Orientez-la vers l'ext\u00E9rieur, \u00E0 travers la vitre.\",\"A flat-panel directional antenna concentrates its signal in one direction (toward a town, farm or valley) and covers little behind it. Aim it during installation.\":\"Une antenne directionnelle plate concentre son signal dans une seule direction (vers un village, une ferme ou une vall\u00E9e) et couvre peu derri\u00E8re elle. Orientez-la pendant l'installation.\",\"Indoors, a low-gain antenna radiates a wide vertical pattern, which suits short distances and signal passing through walls and windows.\":\"\u00C0 l'int\u00E9rieur, une antenne \u00E0 faible gain rayonne selon un large diagramme vertical, ce qui convient aux courtes distances et aux signaux qui traversent murs et fen\u00EAtres.\",\"Mounted well above nearby rooftops, a mid-gain antenna balances distance with enough vertical spread to reach the streets below.\":\"Install\u00E9e bien au-dessus des toits voisins, une antenne \u00E0 gain moyen \u00E9quilibre la port\u00E9e et un \u00E9talement vertical suffisant pour atteindre les rues en contrebas.\",\"Among buildings, a low-gain antenna's wider vertical pattern reaches up and down as well as outward, which generally suits cluttered city surroundings.\":\"Entre les b\u00E2timents, le diagramme vertical plus large d'une antenne \u00E0 faible gain couvre vers le haut et vers le bas autant que vers l'ext\u00E9rieur, ce qui convient g\u00E9n\u00E9ralement aux milieux urbains encombr\u00E9s.\",\"From a high point above hills or valleys, a low-gain antenna's wider vertical pattern can still point signal down into terrain below. Higher gain flattens the pattern toward the horizon.\":\"D'un point \u00E9lev\u00E9 au-dessus de collines ou de vall\u00E9es, le diagramme vertical plus large d'une antenne \u00E0 faible gain peut encore diriger le signal vers le terrain en contrebas. Un gain plus \u00E9lev\u00E9 aplatit le diagramme vers l'horizon.\",\"In rolling terrain, a mid-gain antenna is a common compromise between distance and vertical spread.\":\"En terrain vallonn\u00E9, une antenne \u00E0 gain moyen est un compromis courant entre port\u00E9e et \u00E9talement vertical.\",\"Over flat, open land with a clear view, higher gain concentrates signal toward the horizon, where most of the area is.\":\"Sur un terrain plat et d\u00E9gag\u00E9, un gain plus \u00E9lev\u00E9 concentre le signal vers l'horizon, l\u00E0 o\u00F9 se trouve la plus grande partie de la zone.\",\"At lower heights, a mid-gain antenna avoids a beam so flat that it passes over nearby obstacles.\":\"\u00C0 faible hauteur, une antenne \u00E0 gain moyen \u00E9vite un faisceau si plat qu'il passerait au-dessus des obstacles proches.\",\"In suburbs and towns, a mid-gain omnidirectional antenna is the common choice, balancing distance with vertical spread.\":\"En banlieue et dans les petites villes, une antenne omnidirectionnelle \u00E0 gain moyen est le choix courant\u00A0: elle \u00E9quilibre la port\u00E9e et l'\u00E9talement vertical.\",\"N-male to N-male adaptor. The flat panel has a female connector, so this joins it to the cable.\":\"Adaptateur N m\u00E2le \u00E0 N m\u00E2le. Le panneau plat a un connecteur femelle\u00A0: cet adaptateur le raccorde au c\u00E2ble.\",\"Short LMR-400 low-loss cable (N-female to RP-SMA-male) from the panel to your hotspot. Stand the panel at the window facing outside.\":\"C\u00E2ble court LMR-400 \u00E0 faible perte (N femelle \u00E0 RP-SMA m\u00E2le), du panneau \u00E0 votre hotspot. Placez le panneau \u00E0 la fen\u00EAtre, tourn\u00E9 vers l'ext\u00E9rieur.\",\"Indoor-only magnetic base with a built-in 2 m low-loss cable (N-female to RP-SMA-male). Place the antenna at the window with the clearest outside view.\":\"Base magn\u00E9tique pour l'int\u00E9rieur seulement, avec c\u00E2ble int\u00E9gr\u00E9 de 2 m \u00E0 faible perte (N femelle \u00E0 RP-SMA m\u00E2le). Placez l'antenne \u00E0 la fen\u00EAtre qui offre la vue la plus d\u00E9gag\u00E9e sur l'ext\u00E9rieur.\",\"The base cable is 2 m long, so the hotspot needs to sit within 2 m of the antenna.\":\"Le c\u00E2ble de la base mesure 2 m\u00A0: le hotspot doit donc se trouver \u00E0 moins de 2 m de l'antenne.\",\"Short LMR-400 low-loss cable (N-female to RP-SMA-male) from the antenna to your hotspot. Stand the antenna upright at the window with the clearest outside view.\":\"C\u00E2ble court LMR-400 \u00E0 faible perte (N femelle \u00E0 RP-SMA m\u00E2le), de l'antenne \u00E0 votre hotspot. Placez l'antenne debout \u00E0 la fen\u00EAtre qui offre la vue la plus d\u00E9gag\u00E9e sur l'ext\u00E9rieur.\",\"Bond its ground lug to your building's grounding system per local electrical code.\":\"Reliez sa borne de mise \u00E0 la terre au syst\u00E8me de mise \u00E0 la terre du b\u00E2timent, conform\u00E9ment au code \u00E9lectrique local.\",\"LMR-400 low-loss cable (N-female to N-male) from the antenna down to the arrestor where the cable enters the building.\":\"C\u00E2ble LMR-400 \u00E0 faible perte (N femelle \u00E0 N m\u00E2le), de l'antenne jusqu'au parafoudre, l\u00E0 o\u00F9 le c\u00E2ble entre dans le b\u00E2timent.\",\"Our longest cable is {len}, shorter than your outdoor run. Move the hotspot closer to the antenna, or put it outside in an enclosure beside the antenna.\":\"Notre c\u00E2ble le plus long mesure {len}, moins que votre parcours ext\u00E9rieur. Rapprochez le hotspot de l'antenne, ou installez-le \u00E0 l'ext\u00E9rieur dans un bo\u00EEtier \u00E0 c\u00F4t\u00E9 de l'antenne.\",\"Our longest cable is {len}, shorter than your {run} m run. Move the hotspot closer to the antenna, or put it outside in an enclosure beside the antenna.\":\"Notre c\u00E2ble le plus long mesure {len}, moins que votre parcours de {run} m. Rapprochez le hotspot de l'antenne, ou installez-le \u00E0 l'ext\u00E9rieur dans un bo\u00EEtier \u00E0 c\u00F4t\u00E9 de l'antenne.\",\"Laird lightning surge arrestor (N-female both ends, rated 0\u20131000 MHz). Fit it where the cable enters the building.\":\"Parafoudre Laird (N femelle aux deux extr\u00E9mit\u00E9s, de 0 \u00E0 1000 MHz). Installez-le l\u00E0 o\u00F9 le c\u00E2ble entre dans le b\u00E2timent.\",\"Flat 1 m LMR-100A cable (N-male to RP-SMA-male). It screws straight onto the Laird arrestor, so no adaptor is needed, and runs under a closed window or door to your hotspot.\":\"C\u00E2ble plat LMR-100A de 1 m (N m\u00E2le \u00E0 RP-SMA m\u00E2le). Il se visse directement sur le parafoudre Laird, sans adaptateur, et passe sous une fen\u00EAtre ou une porte ferm\u00E9e jusqu'\u00E0 votre hotspot.\",\"Flat 1 m LMR-100A cable (N-male to RP-SMA-male) from the arrestor through your wall entry to the hotspot. It screws straight onto the Laird arrestor, so no adaptor is needed.\":\"C\u00E2ble plat LMR-100A de 1 m (N m\u00E2le \u00E0 RP-SMA m\u00E2le), du parafoudre jusqu'au hotspot en passant par l'entr\u00E9e murale. Il se visse directement sur le parafoudre Laird, sans adaptateur.\",\"Laird lightning surge arrestor (N-female both ends, rated 0\u20131000 MHz) for the outdoor antenna line.\":\"Parafoudre Laird (N femelle aux deux extr\u00E9mit\u00E9s, de 0 \u00E0 1000 MHz) pour la ligne d'antenne ext\u00E9rieure.\",\"Two N-male to N-male adaptors: one joins the directional antenna (N-female) to the arrestor, one joins the arrestor to the cable.\":\"Deux adaptateurs N m\u00E2le \u00E0 N m\u00E2le\u00A0: l'un raccorde l'antenne directionnelle (N femelle) au parafoudre, l'autre raccorde le parafoudre au c\u00E2ble.\",\"N-male to N-male adaptor. The Laird arrestor is N-female on both ends, so this joins it to the next cable.\":\"Adaptateur N m\u00E2le \u00E0 N m\u00E2le. Le parafoudre Laird est N femelle aux deux extr\u00E9mit\u00E9s\u00A0: cet adaptateur le raccorde au c\u00E2ble suivant.\",\"Lightning arrestor (N-male to N-female) for the outdoor antenna line.\":\"Parafoudre (N m\u00E2le \u00E0 N femelle) pour la ligne d'antenne ext\u00E9rieure.\",\"N-male to N-male adaptor. The directional antenna has a female connector, so this joins the arrestor to the next cable.\":\"Adaptateur N m\u00E2le \u00E0 N m\u00E2le. L'antenne directionnelle a un connecteur femelle\u00A0: cet adaptateur raccorde le parafoudre au c\u00E2ble suivant.\",\"Weatherproof IP67 enclosure kit for your hotspot, with PoE injector and splitter, pole-mount kit and an antenna pigtail (N-female to RP-SMA-male), so the hotspot sits beside the antenna.\":\"Trousse de bo\u00EEtier \u00E9tanche IP67 pour votre hotspot, avec injecteur et s\u00E9parateur PoE, trousse de fixation sur poteau et c\u00E2ble amorce d'antenne (N femelle \u00E0 RP-SMA m\u00E2le), pour installer le hotspot \u00E0 c\u00F4t\u00E9 de l'antenne.\",\"This enclosure kit fits RAK hotspots, RAK7244 and most similar gateways. Please contact us to confirm it fits your hotspot before ordering.\":\"Cette trousse de bo\u00EEtier convient aux hotspots RAK, au RAK7244 et \u00E0 la plupart des passerelles semblables. Veuillez nous contacter pour confirmer qu'elle convient \u00E0 votre hotspot avant de commander.\",\"LMR-400 low-loss cable (N-female to N-male) for the outdoor run from the arrestor to the window.\":\"C\u00E2ble LMR-400 \u00E0 faible perte (N femelle \u00E0 N m\u00E2le) pour le parcours ext\u00E9rieur, du parafoudre \u00E0 la fen\u00EAtre.\",\"Flat 1 m LMR-100A window pass (N-female to RP-SMA-male). It runs under a closed window or door, so you don't need to drill.\":\"Passe-fen\u00EAtre plat LMR-100A de 1 m (N femelle \u00E0 RP-SMA m\u00E2le). Il passe sous une fen\u00EAtre ou une porte ferm\u00E9e\u00A0: aucun per\u00E7age n\u00E9cessaire.\",\"LMR-400 low-loss cable (N-female to RP-SMA-male) from the arrestor to your hotspot.\":\"C\u00E2ble LMR-400 \u00E0 faible perte (N femelle \u00E0 RP-SMA m\u00E2le), du parafoudre \u00E0 votre hotspot.\",\"L-type wall bracket that holds the antenna away from the wall or a mast.\":\"Support mural en L qui maintient l'antenne \u00E0 l'\u00E9cart du mur ou d'un m\u00E2t.\",\"U-shaped hoisting pole for roof, chimney or mast mounting.\":\"Poteau de levage en U pour fixation sur un toit, une chemin\u00E9e ou un m\u00E2t.\",\"Wall bracket to stand the antenna off a rafter or gable wall.\":\"Support mural pour \u00E9loigner l'antenne d'un chevron ou d'un mur pignon.\",\"Metal roofing, solar panels and foil-backed insulation block radio signals. A gable-end wall is usually the clearest spot in an attic.\":\"Les toitures en m\u00E9tal, les panneaux solaires et l'isolant \u00E0 pare-vapeur d'aluminium bloquent les signaux radio. Le mur pignon est habituellement l'endroit le plus d\u00E9gag\u00E9 d'un grenier.\",\"L-type wall bracket that holds the antenna away from the wall.\":\"Support mural en L qui maintient l'antenne \u00E0 l'\u00E9cart du mur.\",\"For a hotspot in an outdoor enclosure we suggest the SenseCAP M1, because the enclosure kit is made for it.\":\"Pour un hotspot dans un bo\u00EEtier ext\u00E9rieur, nous sugg\u00E9rons le SenseCAP M1, car la trousse de bo\u00EEtier est con\u00E7ue pour lui.\",\"Feedline loss is over 3 dB, which means less than half the hotspot's power reaches the antenna. A shorter run or an outdoor enclosure would reduce it.\":\"La perte de la ligne d\u00E9passe 3 dB\u00A0: moins de la moiti\u00E9 de la puissance du hotspot atteint l'antenne. Un parcours plus court ou un bo\u00EEtier ext\u00E9rieur la r\u00E9duirait.\",\"SenseCAP M1 indoor LoRaWAN hotspot (US915). It has an RP-SMA antenna port for the cable above and connects to your router by Ethernet or Wi-Fi. Set it up with the official Helium Wallet app. All sales final.\":\"Hotspot LoRaWAN int\u00E9rieur SenseCAP M1 (US915). Il a un port d'antenne RP-SMA pour le c\u00E2ble ci-dessus et se connecte \u00E0 votre routeur par Ethernet ou Wi-Fi. Configurez-le avec l'application officielle Helium Wallet. Toutes les ventes sont finales.\",\"Directional antenna (N-female)\":\"Antenne directionnelle (N femelle)\",\"Antenna (N-male)\":\"Antenne (N m\u00E2le)\",\"Antenna\":\"Antenne\",\"N-male/N-male adaptor\":\"Adaptateur N m\u00E2le/N m\u00E2le\",\"LMR-400 {len}\":\"LMR-400 {len}\",\"Adaptor\":\"Adaptateur\",\"{n} connections\":\"{n} connexions\",\"Magnetic base, 2 m LMR-200\":\"Base magn\u00E9tique, LMR-200 de 2 m\",\"2 m LMR-200 (base cable)\":\"LMR-200 de 2 m (c\u00E2ble de la base)\",\"Laird arrestor (N-female/N-female)\":\"Parafoudre Laird (N femelle/N femelle)\",\"Laird arrestor (spec <0.25 dB at 1000 MHz)\":\"Parafoudre Laird (sp\u00E9c. < 0,25 dB \u00E0 1000 MHz)\",\"Window pass, 1 m (N-male to RP-SMA-male)\":\"Passe-fen\u00EAtre, 1 m (N m\u00E2le \u00E0 RP-SMA m\u00E2le)\",\"Window pass, 1 m\":\"Passe-fen\u00EAtre, 1 m\",\"1 m LMR-100A window pass\":\"Passe-fen\u00EAtre LMR-100A de 1 m\",\"Lightning arrestor\":\"Parafoudre\",\"Lightning arrestor (spec \u22640.2 dB)\":\"Parafoudre (sp\u00E9c. \u2264 0,2 dB)\",\"Enclosure pigtail (included)\":\"C\u00E2ble amorce du bo\u00EEtier (inclus)\",\"Hotspot in enclosure (RP-SMA)\":\"Hotspot dans le bo\u00EEtier (RP-SMA)\",\"Hotspot (RP-SMA)\":\"Hotspot (RP-SMA)\",\"ROUTER\":\"ROUTEUR\",\"HOTSPOT\":\"HOTSPOT\",\"INDOORS AT A WINDOW\":\"\u00C0 L'INT\u00C9RIEUR, PR\u00C8S D'UNE FEN\u00CATRE\",\"ATTIC\":\"GRENIER\",\"OUTSIDE WALL\":\"MUR EXT\u00C9RIEUR\",\"ROOF / MAST\":\"TOIT / M\u00C2T\",\"DENSE CITY\":\"CENTRE-VILLE DENSE\",\"SUBURBS / TOWN\":\"BANLIEUE / PETITE VILLE\",\"OPEN COUNTRYSIDE\":\"CAMPAGNE D\u00C9GAG\u00C9E\",\"HILLS / VALLEYS\":\"COLLINES / VALL\u00C9ES\",\"Diagram of the setup: antenna {location}, surroundings {environment}. Signal path: {chain}.\":\"Sch\u00E9ma de l'installation\u00A0: antenne {location}, environnement {environment}. Trajet du signal\u00A0: {chain}.\",\", then \":\", puis \",\"Nebra ROCK Pi indoor LoRaWAN hotspot (US915). It has an RP-SMA antenna port for the cable above and connects to your router by Ethernet or Wi-Fi. Nebra hasn\u2019t kept up its onboarding credits, so you may need to pay Helium\u2019s onboarding fee yourself (4,000,000 DC, about USD $40) or arrange it with Nebra. All sales final.\":\"Hotspot LoRaWAN int\u00E9rieur Nebra ROCK Pi (US915). Il a un port d'antenne RP-SMA pour le c\u00E2ble ci-dessus et se connecte \u00E0 votre routeur par Ethernet ou Wi-Fi. Nebra n'a pas maintenu ses cr\u00E9dits d'int\u00E9gration\u00A0: vous devrez peut-\u00EAtre payer vous-m\u00EAme les frais d'int\u00E9gration de Helium (4\u202F000 000 DC, environ 40 $ US) ou vous arranger avec Nebra. Toutes les ventes sont finales.\"};\n  if (!FR && typeof require === 'function') FR = require('./fr.json').strings;\n\n  var lang = 'en';\n\n  function setLang(code) { lang = /^fr/i.test(code || '') ? 'fr' : 'en'; }\n  function getLang() { return lang; }\n\n  function t(s, vars) {\n    var out = lang === 'fr' && FR && FR[s] != null ? FR[s] : s;\n    if (vars) out = out.replace(/\\{(\\w+)\\}/g, function (m, k) { return k in vars ? vars[k] : m; });\n    return out;\n  }\n\n  /** A number in the page's style: 7.5 in English, 7,5 in French. digits = exact decimals. */\n  function num(n, digits) {\n    var opts = digits == null ? { maximumFractionDigits: 2 } : { minimumFractionDigits: digits, maximumFractionDigits: digits };\n    try { return Number(n).toLocaleString(lang === 'fr' ? 'fr-CA' : 'en-CA', opts); } catch (e) { return String(n); }\n  }\n\n  var api = { t: t, num: num, setLang: setLang, lang: getLang };\n  if (typeof module !== 'undefined' && module.exports) module.exports = api;\n  else global.MNSPi18n = api;\n})(typeof window !== 'undefined' ? window : globalThis);\n\n/*\n * Mapping Network Setup Planner: live blueprint diagram.\n *\n * draw(input, result) returns an SVG string that redraws the install the\n * customer is describing: a close-up of a window for indoor setups, or a\n * cut-away house for attic, outside-wall and roof setups, with the\n * surroundings (city, suburbs, countryside, hills) in the background. Every\n * suggested part gets a numbered callout that matches the parts list.\n *\n * Pure string building (no DOM), so it is unit tested in Node. Colours come\n * from CSS classes (.bp-*) so the theme editor can switch between a blue\n * blueprint and a black-and-white drawing.\n */\n(function (global) {\n  'use strict';\n\n  var L = typeof module !== 'undefined' && module.exports ? require('./i18n.js') : global.MNSPi18n;\n  var t = L.t;\n\n  var W = 640, H = 400;\n\n  function f(n) { return Math.round(n * 10) / 10; }\n  function esc(s) {\n    return String(s == null ? '' : s).replace(/[&<>\"']/g, function (c) {\n      return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' }[c];\n    });\n  }\n  function line(x1, y1, x2, y2, cls) { return '<line x1=\"' + f(x1) + '\" y1=\"' + f(y1) + '\" x2=\"' + f(x2) + '\" y2=\"' + f(y2) + '\" class=\"' + (cls || 'bp-s') + '\"/>'; }\n  function path(d, cls, extra) { return '<path d=\"' + d + '\" class=\"' + (cls || 'bp-s') + '\"' + (extra || '') + '/>'; }\n  // The signal path: a solid line that draws itself in, with a flow of dashes on top (CSS animates both).\n  function sig(d, flat) {\n    return '<path d=\"' + d + '\" pathLength=\"1\" class=\"bp-sig-draw' + (flat ? ' bp-flat' : '') + '\"/>' +\n      (flat ? '' : '<path d=\"' + d + '\" class=\"bp-sig-flow\"/>');\n  }\n  function rect(x, y, w, h, cls, rx) { return '<rect x=\"' + f(x) + '\" y=\"' + f(y) + '\" width=\"' + f(w) + '\" height=\"' + f(h) + '\"' + (rx ? ' rx=\"' + rx + '\"' : '') + ' class=\"' + (cls || 'bp-s') + '\"/>'; }\n  function circle(cx, cy, r, cls) { return '<circle cx=\"' + f(cx) + '\" cy=\"' + f(cy) + '\" r=\"' + r + '\" class=\"' + (cls || 'bp-s') + '\"/>'; }\n  function text(x, y, s, cls, anchor) { return '<text x=\"' + f(x) + '\" y=\"' + f(y) + '\" class=\"' + (cls || 'bp-t') + '\"' + (anchor ? ' text-anchor=\"' + anchor + '\"' : '') + '>' + esc(s) + '</text>'; }\n  function poly(pts) { return pts.map(function (p, i) { return (i ? 'L' : 'M') + f(p[0]) + ' ' + f(p[1]); }).join(' '); }\n\n  // ------------------------------------------------------------ surroundings\n\n  /** Silhouettes of the surroundings between x0 and x1, standing on groundY. */\n  function backdrop(env, x0, x1, groundY, k) {\n    k = k || 1;\n    var out = [];\n    var span = x1 - x0;\n    if (env === 'city') {\n      var hs = [70, 110, 55, 135, 85, 120, 60, 95];\n      var n = Math.max(3, Math.round(span / (34 * k)));\n      var bw = span / n;\n      for (var i = 0; i < n; i++) {\n        var bh = hs[i % hs.length] * k;\n        var bx = x0 + i * bw + 3;\n        out.push(rect(bx, groundY - bh, bw - 6, bh, 'bp-far'));\n        for (var wy = groundY - bh + 10 * k; wy < groundY - 8 * k; wy += 14 * k) {\n          out.push(line(bx + 5, wy, bx + bw - 11, wy, 'bp-far bp-faint'));\n        }\n      }\n    } else if (env === 'suburban') {\n      var step = 78 * k;\n      for (var hx = x0 + 6; hx + 44 * k < x1; hx += step) {\n        var w = 40 * k, h = 24 * k;\n        out.push(path(poly([[hx, groundY], [hx, groundY - h], [hx + w / 2, groundY - h - 16 * k], [hx + w, groundY - h], [hx + w, groundY], [hx, groundY]]), 'bp-far'));\n        out.push(rect(hx + w * 0.38, groundY - 12 * k, w * 0.24, 12 * k, 'bp-far'));\n        var tx = hx + w + 16 * k;\n        if (tx + 10 * k < x1) {\n          out.push(line(tx, groundY, tx, groundY - 14 * k, 'bp-far'));\n          out.push(circle(tx, groundY - 24 * k, 11 * k, 'bp-far'));\n        }\n      }\n    } else if (env === 'rural') {\n      out.push(line(x0, groundY - 2, x1, groundY - 2, 'bp-far bp-faint'));\n      for (var px = x0 + 4; px < x1; px += 22 * k) out.push(line(px, groundY, px, groundY - 10 * k, 'bp-far'));\n      out.push(line(x0, groundY - 7 * k, x1, groundY - 7 * k, 'bp-far'));\n      var bx2 = x0 + span * 0.55;\n      if (bx2 + 50 * k < x1) {\n        out.push(path(poly([[bx2, groundY], [bx2, groundY - 26 * k], [bx2 + 18 * k, groundY - 40 * k], [bx2 + 36 * k, groundY - 26 * k], [bx2 + 36 * k, groundY]]), 'bp-far'));\n        out.push(rect(bx2 + 40 * k, groundY - 52 * k, 12 * k, 52 * k, 'bp-far', 5));\n      }\n    } else if (env === 'hilly') {\n      out.push(path('M' + f(x0) + ' ' + f(groundY) + ' Q ' + f(x0 + span * 0.25) + ' ' + f(groundY - 120 * k) + ' ' + f(x0 + span * 0.5) + ' ' + f(groundY - 30 * k) + ' T ' + f(x1) + ' ' + f(groundY - 50 * k), 'bp-far'));\n      out.push(path('M' + f(x0 + span * 0.15) + ' ' + f(groundY) + ' Q ' + f(x0 + span * 0.6) + ' ' + f(groundY - 80 * k) + ' ' + f(x1) + ' ' + f(groundY - 10 * k), 'bp-far bp-faint'));\n    }\n    return out.join('');\n  }\n\n  // ------------------------------------------------------------ parts\n\n  function antennaShape(x, baseY, directional) {\n    if (directional) {\n      return rect(x - 6, baseY - 46, 12, 46, 'bp-s bp-paper', 2) +\n        line(x - 2, baseY - 40, x - 2, baseY - 6, 'bp-s bp-faint') +\n        path('M' + (x + 10) + ' ' + (baseY - 30) + ' l 22 -8 M' + (x + 10) + ' ' + (baseY - 23) + ' l 26 0 M' + (x + 10) + ' ' + (baseY - 16) + ' l 22 8', 'bp-s bp-faint');\n    }\n    return rect(x - 3, baseY - 62, 6, 56, 'bp-s bp-paper', 3) + rect(x - 4.5, baseY - 6, 9, 6, 'bp-s');\n  }\n\n  /** Flat panel seen from inside the room, facing out through the window. */\n  function panelFront(x, baseY) {\n    return rect(x - 15, baseY - 56, 30, 48, 'bp-s bp-paper', 3) + rect(x - 9, baseY - 50, 18, 36, 'bp-s bp-faint', 2) +\n      line(x, baseY - 8, x, baseY - 2, 'bp-s') + rect(x - 9, baseY - 2, 18, 2, 'bp-s');\n  }\n\n  function antennaShapeLen(x, baseY, len) {\n    return rect(x - 3, baseY - len - 6, 6, len, 'bp-s bp-paper', 3) + rect(x - 4.5, baseY - 6, 9, 6, 'bp-s');\n  }\n\n  /** Rod length follows the recommended gain, so the drawing changes with the antenna. */\n  function antennaLen(gain) { return gain == null || gain <= 3.5 ? 40 : gain <= 6.5 ? 56 : 72; }\n\n  function routerBox(x, y) {\n    // x,y = top-left; 34 x 14, label above\n    return rect(x, y, 34, 14, 'bp-s bp-paper', 2) +\n      line(x + 6, y, x + 4, y - 7, 'bp-s') + line(x + 28, y, x + 30, y - 7, 'bp-s') +\n      circle(x + 7, y + 7, 1.4, 'bp-fill') + circle(x + 12, y + 7, 1.4, 'bp-fill') +\n      text(x + 17, y - 11, t('ROUTER'), 'bp-t bp-small', 'middle');\n  }\n\n  function hotspotBox(x, y, label) {\n    // x,y = top-left; 46 x 20\n    return rect(x, y, 46, 20, 'bp-s bp-paper', 3) +\n      circle(x + 8, y + 10, 1.8, 'bp-fill') + circle(x + 14, y + 10, 1.8, 'bp-fill') +\n      text(x + 23, y + 34, label, 'bp-t bp-small', 'middle');\n  }\n\n  function groundRod(x, groundY) {\n    return line(x, groundY, x, groundY + 16, 'bp-s') +\n      line(x - 8, groundY + 16, x + 8, groundY + 16) + line(x - 5, groundY + 20, x + 5, groundY + 20) + line(x - 2, groundY + 24, x + 2, groundY + 24);\n  }\n\n  function arrestorBox(x, y) { return rect(x - 7, y - 10, 14, 20, 'bp-s bp-paper', 2) + line(x - 3, y - 3, x + 3, y + 3, 'bp-s'); }\n\n  function enclosureBox(x, y) {\n    // x,y = top-left; 40 x 52\n    return rect(x, y, 40, 52, 'bp-s bp-paper', 3) + line(x + 6, y + 8, x + 34, y + 8, 'bp-s bp-faint') +\n      hotspotMini(x + 9, y + 20);\n  }\n  function hotspotMini(x, y) { return rect(x, y, 22, 12, 'bp-s', 2) + circle(x + 5, y + 6, 1.4, 'bp-fill'); }\n\n  // ------------------------------------------------------------ scenes\n\n  /** Close-up of a window from inside the room. */\n  function sceneIndoor(input, has, result, directional) {\n    var o = [];\n    var a = {};\n    // wall around the window\n    o.push(rect(0, 0, W, 300, 'bp-hatch'));\n    o.push('<rect x=\"150\" y=\"40\" width=\"280\" height=\"226\" class=\"bp-bg\"/>');\n    // view through the window\n    // the higher the window, the further the street drops below it\n    var hz = Math.min(Math.max(170 + input.heightM * 5, 180), 262);\n    o.push('<g clip-path=\"url(#mnsp-win)\">' + backdrop(input.environment, 156, 424, hz, 0.75) +\n      line(150, hz, 430, hz, 'bp-far') + '</g>');\n    o.push(rect(150, 40, 280, 226, 'bp-s'));\n    o.push(rect(158, 48, 128, 210, 'bp-s bp-faint'));\n    o.push(rect(294, 48, 128, 210, 'bp-s bp-faint'));\n    o.push(line(290, 40, 290, 266, 'bp-s'));\n    // sill\n    o.push(rect(132, 266, 316, 14, 'bp-s bp-paper'));\n    // room: floor, desk\n    o.push(rect(0, 300, W, 100, 'bp-bg'));\n    o.push(line(0, 372, W, 372, 'bp-s'));\n    o.push(line(450, 330, 630, 330) + line(462, 330, 462, 372) + line(618, 330, 618, 372));\n    // antenna standing on the sill\n    var ax = 350;\n    if (has.mount) o.push('<ellipse cx=\"' + ax + '\" cy=\"262\" rx=\"16\" ry=\"4\" class=\"bp-s bp-paper\"/>');\n    var len = antennaLen(result.antennaGain), base = has.mount ? 258 : 262;\n    if (directional) { base = 262; len = 50; o.push(panelFront(ax, base)); }\n    else o.push(antennaShapeLen(ax, base, len));\n    a.antenna = [ax, base - len * 0.6]; a.mount = [ax + 14, 262]; a.adaptor = [ax + 4, 270, 34, 6];\n    // cable: antenna base, over the sill, down to the desk and the hotspot\n    var hx = 500, hy = 310;\n    o.push(sig('M' + ax + ' 266 L' + ax + ' 274 Q ' + ax + ' 280 ' + (ax + 8) + ' 280 L 448 280 Q 460 280 460 292 L 460 312 Q 460 320 ' + (hx - 10) + ' 320 L ' + hx + ' 320', false));\n    a.cable = [460, 300];\n    o.push(hotspotBox(hx, hy, t('HOTSPOT')));\n    a.hotspot = [hx + 23, hy];\n    o.push(path('M' + (hx + 46) + ' 323 L 572 323', 'bp-eth'));\n    o.push(routerBox(572, 316));\n    return { svg: o.join(''), anchors: a };\n  }\n\n  /** Cut-away house with the antenna in the attic, on an outside wall or on the roof. */\n  function sceneHouse(input, has, result) {\n    var o = [];\n    var a = {};\n    var G = 340, CEIL = 236, PEAK = 150;\n    var SLOPE = (CEIL + 12 - PEAK) / 122; // roof line from (250, PEAK) to (372, CEIL + 12)\n    function roofY(x) { return PEAK + Math.abs(x - 250) * SLOPE; }\n    var loc = input.location;\n    var outside = loc !== 'attic' && input.hotspotPlacement === 'outside';\n    var windowRoute = !outside && loc !== 'attic' && input.route === 'window';\n    var directional = !!(result && result.directional);\n    var h = input.heightM;\n\n    o.push(backdrop(input.environment, 400, 630, G, 1));\n    o.push(backdrop(input.environment, 4, 112, G, 0.8));\n    // ground\n    o.push(line(0, G, W, G, 'bp-s'));\n    for (var gx = 6; gx < W; gx += 14) o.push(line(gx, G + 2, gx - 8, G + 10, 'bp-s bp-faint'));\n    // house cross-section: walls 148-160 and 340-352\n    o.push(rect(148, CEIL, 12, G - CEIL, 'bp-hatch-s'));\n    o.push(rect(340, CEIL, 12, G - CEIL, 'bp-hatch-s'));\n    if (windowRoute) {\n      o.push('<rect x=\"339\" y=\"262\" width=\"14\" height=\"38\" class=\"bp-bg\"/>');\n      o.push(line(346, 262, 346, 300, 'bp-s bp-faint') + line(336, 262, 356, 262) + line(334, 300, 358, 300));\n    }\n    o.push(line(148, CEIL, 352, CEIL, 'bp-s'));\n    o.push(path('M128 ' + (CEIL + 12) + ' L250 ' + PEAK + ' L372 ' + (CEIL + 12), 'bp-s bp-roof'));\n    // table inside\n    o.push(line(244, 316, 332, 316) + line(250, 316, 250, G) + line(326, 316, 326, G));\n\n    var antX, antBase, antLen = antennaLen(result && result.gain);\n    if (loc === 'roof') {\n      var mast = Math.min(Math.max(30 + h * 2.4, 40), PEAK - antLen - 14);\n      antX = 250; antBase = PEAK - mast;\n      o.push(rect(247, antBase, 6, mast + 4, 'bp-s bp-paper'));\n      o.push(path('M236 ' + (PEAK + 6) + ' L264 ' + (PEAK + 6) + ' M240 ' + (PEAK - 6) + ' l0 14 M260 ' + (PEAK - 6) + ' l0 14', 'bp-s'));\n      a.mount = [262, PEAK - 2, 40, 6];\n    } else if (loc === 'attic') {\n      antX = 276; antBase = CEIL - 8; antLen = antLen <= 40 ? 32 : antLen <= 56 ? 40 : 46; // stays under the roof\n      o.push(path('M' + (antX + 20) + ' ' + f(roofY(antX + 20) + 2) + ' L' + (antX + 20) + ' ' + (antBase - 22) + ' L' + (antX + 3) + ' ' + (antBase - 22), 'bp-s'));\n      a.mount = [antX + 20, antBase - 30];\n    } else {\n      // outside wall: the bracket height follows the slider (drawing not to scale)\n      antX = 396;\n      var bracketY = Math.min(Math.max(G - 30 - h * 12, 236), 262);\n      antBase = bracketY + 18;\n      o.push(path('M352 ' + bracketY + ' L' + (antX - 3) + ' ' + bracketY + ' M352 ' + (bracketY - 10) + ' L352 ' + (bracketY + 10), 'bp-s'));\n      a.mount = [372, bracketY];\n    }\n    o.push(directional ? antennaShape(antX, antBase, true) : antennaShapeLen(antX, antBase, antLen));\n    a.antenna = [antX, antBase - antLen * 0.6];\n\n    var arrX, arrY, gnd;\n    if (outside) {\n      // enclosure beside the antenna; Ethernet with PoE runs into the house to the injector\n      var ex, ey, eth;\n      var exIn; // x where the pigtail enters the enclosure\n      if (loc === 'roof') {\n        // enclosure on the left of the mast, Ethernet down the left roof and wall\n        arrX = antX; arrY = antBase + 16; ex = 194; ey = antBase + 6; exIn = ex + 40;\n        eth = 'M214 ' + (ey + 52) + ' L214 ' + f(roofY(214) - 5) + ' L138 ' + f(roofY(138) - 5) + ' L138 328 L300 328 L300 316';\n      } else {\n        arrX = antX; arrY = antBase + 16; ex = 420; ey = antBase + 2;\n        var yr = Math.min(ey + 62, 332);\n        eth = 'M440 ' + (ey + 52) + ' L440 ' + yr + ' L300 ' + yr + ' L300 316';\n        exIn = ex;\n      }\n      o.push(enclosureBox(ex, ey));\n      o.push(sig('M' + antX + ' ' + antBase + ' L' + antX + ' ' + (arrY - 10) + ' M' + antX + ' ' + (arrY + 10) + ' L' + antX + ' ' + (arrY + 16) + ' L' + exIn + ' ' + (arrY + 16), false));\n      if (has.arrestor) o.push(arrestorBox(arrX, arrY));\n      o.push(path(eth, 'bp-eth'));\n      o.push(rect(282, 306, 36, 10, 'bp-s bp-paper', 2));\n      o.push(path('M282 311 L214 311 L214 333 L200 333', 'bp-eth'));\n      o.push(routerBox(166, 326));\n      var left = loc === 'roof';\n      a.enclosure = left ? [ex, ey + 40, -30, 14] : [ex + 40, ey + 40, 30, 14];\n      a.hotspot = left ? [ex + 11, ey + 24, -40, -26] : [ex + 31, ey + 24, 36, -20];\n      a.arrestor = left ? [arrX + 7, arrY, 34, -8] : [arrX - 7, arrY, -36, -8];\n      a.adaptor = left ? [arrX + 7, arrY + 8, 34, 18] : [arrX - 7, arrY + 8, -36, 18];\n      a.cable = null;\n    } else {\n      var hx = 262, hy = 296, portY = 306;\n      o.push(hotspotBox(hx, hy, t('HOTSPOT')));\n      a.hotspot = [hx + 23, hy];\n      var cable, flat = null;\n      if (loc === 'attic') {\n        arrX = 318; arrY = 266;\n        cable = 'M' + antX + ' ' + antBase + ' L' + antX + ' ' + (CEIL + 8) + ' Q' + antX + ' ' + (CEIL + 14) + ' ' + (antX + 6) + ' ' + (CEIL + 14) + ' L' + (arrX - 6) + ' ' + (CEIL + 14) + ' Q' + arrX + ' ' + (CEIL + 14) + ' ' + arrX + ' ' + (CEIL + 20) + ' L' + arrX + ' ' + (arrY - 10) +\n          ' M' + arrX + ' ' + (arrY + 10) + ' L' + arrX + ' ' + (portY - 6) + ' Q' + arrX + ' ' + portY + ' ' + (arrX - 6) + ' ' + portY + ' L' + (hx + 46) + ' ' + portY;\n        a.cable = [antX + 22, CEIL + 14];\n        a.windowpass = [arrX, arrY + 22];\n        gnd = 'M' + (arrX + 7) + ' ' + arrY + ' L332 ' + arrY + ' L332 ' + G;\n        o.push(groundRod(332, G));\n      } else {\n        var downX = loc === 'roof' ? 366 : antX;\n        arrX = downX; arrY = loc === 'roof' ? 270 : Math.min(antBase + 16, 288);\n        var top = loc === 'roof'\n          ? 'M' + antX + ' ' + antBase + ' L' + antX + ' ' + (antBase + 8) + ' L258 ' + (antBase + 8) + ' L258 ' + (PEAK - 6) + ' L366 ' + f(roofY(366) - 6) + ' L366 ' + (arrY - 10)\n          : 'M' + antX + ' ' + antBase + ' L' + antX + ' ' + (arrY - 10);\n        var entryY = windowRoute ? 303 : portY;\n        var after = ' M' + downX + ' ' + (arrY + 10) + ' L' + downX + ' ' + (entryY - 6) + ' Q' + downX + ' ' + entryY + ' ' + (downX - 6) + ' ' + entryY + ' L' + (hx + 46) + ' ' + entryY;\n        if (windowRoute) { cable = top; flat = after; }\n        else cable = top + after;\n        a.cable = loc === 'roof' ? [314, f(roofY(314) - 6)] : [antX, (antBase + arrY) / 2];\n        a.windowpass = [346, entryY];\n        gnd = 'M' + (downX + 7) + ' ' + arrY + ' L' + (downX + 18) + ' ' + arrY + ' L' + (downX + 18) + ' ' + G;\n        o.push(groundRod(downX + 18, G));\n        if (!windowRoute) o.push(circle(346, portY, 3, 'bp-s'));\n      }\n      o.push(sig(cable, false));\n      if (flat) o.push(sig(flat, true));\n      if (has.arrestor) { o.push(arrestorBox(arrX, arrY)); o.push(path(gnd, 'bp-gnd')); }\n      a.arrestor = [arrX, arrY];\n      a.adaptor = [arrX, arrY + 8];\n      o.push(path('M' + hx + ' 312 L214 312 L214 333 L200 333', 'bp-eth'));\n      o.push(routerBox(166, 326));\n    }\n    if (outside && has.arrestor) {\n      // bond the arrestor to ground: down the mast and wall (roof) or straight down the wall\n      var gpath = loc === 'roof'\n        ? 'M' + (arrX + 7) + ' ' + arrY + ' L258 ' + arrY + ' L258 ' + (PEAK - 4) + ' L380 ' + (CEIL + 8) + ' L380 ' + G\n        : 'M' + (arrX - 7) + ' ' + arrY + ' L376 ' + arrY + ' L376 ' + G;\n      o.push(path(gpath, 'bp-gnd'));\n      o.push(groundRod(loc === 'roof' ? 380 : 376, G));\n    }\n\n    // height dimension\n    var dimX = loc === 'wall' ? 500 : 470;\n    var dimTop = antBase;\n    o.push(line(dimX, G, dimX, dimTop, 'bp-dim') + line(dimX - 6, dimTop, dimX + 6, dimTop, 'bp-s') + line(dimX - 6, G, dimX + 6, G, 'bp-s'));\n    o.push(path('M' + dimX + ' ' + dimTop + ' l -4 8 l 8 0 z M' + dimX + ' ' + G + ' l -4 -8 l 8 0 z', 'bp-fill'));\n    o.push(line(antX + 10, dimTop, dimX - 8, dimTop, 'bp-dim'));\n    return { svg: o.join(''), anchors: a };\n  }\n\n  // ------------------------------------------------------------ callouts\n\n  var ROLE_ANCHOR = {\n    antenna_low: 'antenna', antenna_mid: 'antenna', antenna_high: 'antenna', antenna_directional: 'antenna',\n    cable_rpsma: 'cable', cable_nm: 'cable', window_pass: 'windowpass', window_pass_nm: 'windowpass',\n    arrestor: 'arrestor', arrestor_nf: 'arrestor', adaptor_nm_nm: 'adaptor',\n    mount_indoor: 'mount', mount_wall: 'mount', mount_mast: 'mount',\n    enclosure_m1: 'enclosure', enclosure_gateway: 'enclosure', enclosure_bobcat: 'enclosure',\n    hotspot_m1: 'hotspot', hotspot_nebra: 'hotspot'\n  };\n  // Where each callout bubble sits relative to its anchor.\n  var OFFSET = {\n    antenna: [40, -30], cable: [-40, 10], windowpass: [40, 34], arrestor: [40, -14], adaptor: [40, 18],\n    mount: [-40, -14], enclosure: [34, 18], hotspot: [-34, -26]\n  };\n\n  function anchorKey(role) { return ROLE_ANCHOR[role] || null; }\n\n  function callouts(items, anchors, vb) {\n    var x0 = vb[0], y0 = vb[1], x1 = vb[0] + vb[2], y1 = vb[1] + vb[3];\n    var out = [];\n    var used = {};\n    var placed = [];\n    items.forEach(function (it, i) {\n      var key = anchorKey(it.role);\n      var at = key && anchors[key];\n      if (!at) return;\n      var off = at.length > 2 ? [at[2], at[3]] : (OFFSET[key] || [30, -20]);\n      var n = (used[key] = (used[key] || 0) + 1);\n      var bx = Math.min(Math.max(at[0] + off[0] + (n - 1) * 22, x0 + 14), x1 - 14);\n      var by = Math.min(Math.max(at[1] + off[1], y0 + 14), y1 - 60);\n      // keep bubbles from sitting on top of each other\n      for (var tries = 0; tries < 8 && placed.some(function (q) { return Math.abs(q[0] - bx) < 24 && Math.abs(q[1] - by) < 24; }); tries++) {\n        by += by > y1 - 90 ? -26 : 26;\n      }\n      placed.push([bx, by]);\n      out.push('<g class=\"bp-callout\" data-n=\"' + (i + 1) + '\" style=\"--i:' + i + '\">' + line(at[0], at[1], bx, by, 'bp-lead') +\n        circle(at[0], at[1], 2.5, 'bp-accent-fill') + circle(bx, by, 11, 'bp-tag') +\n        '<text x=\"' + f(bx) + '\" y=\"' + f(by + 4) + '\" text-anchor=\"middle\" class=\"bp-tag-t\">' + (i + 1) + '</text></g>');\n    });\n    return out.join('');\n  }\n\n  var LOC_LABEL = { indoor: 'INDOORS AT A WINDOW', attic: 'ATTIC', wall: 'OUTSIDE WALL', roof: 'ROOF / MAST' };\n  var ENV_LABEL = { city: 'DENSE CITY', suburban: 'SUBURBS / TOWN', rural: 'OPEN COUNTRYSIDE', hilly: 'HILLS / VALLEYS' };\n\n  function describe(input, result) {\n    return t('Diagram of the setup: antenna {location}, surroundings {environment}. Signal path: {chain}.', {\n      location: t(LOC_LABEL[input.location] || '').toLowerCase(),\n      environment: t(ENV_LABEL[input.environment] || '').toLowerCase(),\n      chain: (result.chain || []).join(t(', then '))\n    });\n  }\n\n  /**\n   * input: the planner's form input. result: recommend() output (items, chain).\n   * Returns an SVG string.\n   */\n  function draw(input, result) {\n    result = result || { items: [], chain: [] };\n    var has = {};\n    (result.items || []).forEach(function (it) { var k = anchorKey(it.role); if (k) has[k] = true; });\n    var directional = (result.items || []).some(function (it) { return it.role === 'antenna_directional'; });\n    var scene = input.location === 'indoor'\n      ? sceneIndoor(input, has, result, directional)\n      : sceneHouse(input, has, { directional: directional, gain: result.antennaGain });\n    var desc = describe(input, result);\n    // Zoom in on low installs (wall, attic) so the house fills the frame; same 8:5 shape for every scene.\n    var vb = input.location === 'wall' || input.location === 'attic' ? [64, 80, 512, 320] : [0, 0, W, H];\n    return '<svg class=\"mnsp-bp__svg\" viewBox=\"' + vb.join(' ') + '\" role=\"img\" aria-labelledby=\"mnsp-bp-d\" xmlns=\"http://www.w3.org/2000/svg\">' +\n      '<desc id=\"mnsp-bp-d\">' + esc(desc) + '</desc>' +\n      '<defs>' +\n        '<pattern id=\"mnsp-grid\" width=\"20\" height=\"20\" patternUnits=\"userSpaceOnUse\"><path d=\"M20 0 L0 0 0 20\" class=\"bp-grid\"/></pattern>' +\n        '<pattern id=\"mnsp-grid5\" width=\"100\" height=\"100\" patternUnits=\"userSpaceOnUse\"><path d=\"M100 0 L0 0 0 100\" class=\"bp-grid bp-grid--major\"/></pattern>' +\n        '<pattern id=\"mnsp-hatch\" width=\"8\" height=\"8\" patternUnits=\"userSpaceOnUse\" patternTransform=\"rotate(45)\"><line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"8\" class=\"bp-hatchline\"/></pattern>' +\n        '<clipPath id=\"mnsp-win\"><rect x=\"150\" y=\"40\" width=\"280\" height=\"226\"/></clipPath>' +\n      '</defs>' +\n      '<rect width=\"' + W + '\" height=\"' + H + '\" class=\"bp-bg\"/>' +\n      '<rect width=\"' + W + '\" height=\"' + H + '\" fill=\"url(#mnsp-grid)\"/>' +\n      '<rect width=\"' + W + '\" height=\"' + H + '\" fill=\"url(#mnsp-grid5)\"/>' +\n      '<g class=\"bp-scene\">' + scene.svg + '</g>' +\n      callouts(result.items || [], scene.anchors, vb) +\n      '</svg>';\n  }\n\n  var api = { draw: draw, anchorKey: anchorKey, ROLE_ANCHOR: ROLE_ANCHOR };\n  if (typeof module !== 'undefined' && module.exports) module.exports = api;\n  else global.MNSPDiagram = api;\n})(typeof window !== 'undefined' ? window : globalThis);\n\n/*\n * Mapping Network Hotspot & Antenna Setup Planner.\n *\n * Recommends a compatible antenna system from the store's catalogue and shows\n * only figures that can be calculated from published specifications:\n * feedline loss (manufacturer datasheets), net gain at the antenna, and the\n * geometric line-of-sight horizon. It deliberately makes no coverage, reward or\n * earnings claims.\n *\n * The logic (recommend, radioHorizonKm, pickVariantForLength, ...) is pure and\n * unit tested in Node. The UI mounts on every [data-mnsp] element and reads the\n * catalogue the Liquid section renders into <script data-mnsp-catalog>.\n */\n(function (global) {\n  'use strict';\n\n  var L = typeof module !== 'undefined' && module.exports ? require('./i18n.js') : global.MNSPi18n;\n  var t = L.t, num = L.num;\n\n  // Attenuation at 900 MHz, Times Microwave datasheets (typical, 25 \u00B0C):\n  // LMR-400 12.8 dB/100 m, LMR-200 32.6 dB/100 m, LMR-100A 74.9 dB/100 m.\n  var LOSS_DB_PER_M = { lmr400: 0.128, lmr200: 0.326, lmr100: 0.749 };\n  // RAKwireless arrestor spec: \u22640.2 dB (0\u20132000 MHz).\n  var ARRESTOR_DB = 0.2;\n  var LAIRD_DB = 0.25; // Laird L350NN: <0.25 dB insertion loss at 1000 MHz\n  // Allowance per mated N / RP-SMA connection or adaptor (stated in the UI as an allowance).\n  var CONNECTION_DB = 0.1;\n  // Magnetic base: 2 m LMR-200, N-female to RP-SMA-male (product spec).\n  var BASE_CABLE_M = 2;\n  // Window pass N-female to RP-SMA-male: 1.0 m LMR-100A (SKU LPV100NFSMRP1.0M).\n  var WINDOW_PASS_M = 1.0;\n  // Height of the device at the other end of the link for the horizon figure.\n  var DEVICE_HEIGHT_M = 1.5;\n\n  function round1(n) { return Math.round(n * 10) / 10; }\n  function round2(n) { return Math.round(n * 100) / 100; }\n\n  /**\n   * Distance to the radio horizon between two antennas, in km, using the\n   * standard 4/3-Earth refraction model: d = 4.12 \u00D7 (\u221Ah1 + \u221Ah2), heights in m.\n   * It is a geometric upper bound over smooth terrain, not a coverage estimate.\n   */\n  function radioHorizonKm(heightM, deviceHeightM) {\n    var h2 = deviceHeightM == null ? DEVICE_HEIGHT_M : deviceHeightM;\n    return round1(4.12 * (Math.sqrt(Math.max(heightM, 0)) + Math.sqrt(h2)));\n  }\n\n  /** Which antenna class suits the site, and the general RF reason. */\n  function chooseAntennaClass(input) {\n    if (input.location === 'indoor' && input.directional) {\n      return { role: 'antenna_directional', why: t('A flat-panel directional antenna concentrates its signal in one direction, so at a window it sends most of it outside toward a town, farm or valley instead of into the room. Face it out through the glass.') };\n    }\n    if (input.directional) {\n      return { role: 'antenna_directional', why: t('A flat-panel directional antenna concentrates its signal in one direction (toward a town, farm or valley) and covers little behind it. Aim it during installation.') };\n    }\n    if (input.location === 'indoor') {\n      return { role: 'antenna_low', why: t('Indoors, a low-gain antenna radiates a wide vertical pattern, which suits short distances and signal passing through walls and windows.') };\n    }\n    var h = input.heightM;\n    switch (input.environment) {\n      case 'city':\n        return h >= 15\n          ? { role: 'antenna_mid', why: t('Mounted well above nearby rooftops, a mid-gain antenna balances distance with enough vertical spread to reach the streets below.') }\n          : { role: 'antenna_low', why: t('Among buildings, a low-gain antenna\\'s wider vertical pattern reaches up and down as well as outward, which generally suits cluttered city surroundings.') };\n      case 'hilly':\n        return h >= 15\n          ? { role: 'antenna_low', why: t('From a high point above hills or valleys, a low-gain antenna\\'s wider vertical pattern can still point signal down into terrain below. Higher gain flattens the pattern toward the horizon.') }\n          : { role: 'antenna_mid', why: t('In rolling terrain, a mid-gain antenna is a common compromise between distance and vertical spread.') };\n      case 'rural':\n        return h >= 6\n          ? { role: 'antenna_high', why: t('Over flat, open land with a clear view, higher gain concentrates signal toward the horizon, where most of the area is.') }\n          : { role: 'antenna_mid', why: t('At lower heights, a mid-gain antenna avoids a beam so flat that it passes over nearby obstacles.') };\n      default:\n        return { role: 'antenna_mid', why: t('In suburbs and towns, a mid-gain omnidirectional antenna is the common choice, balancing distance with vertical spread.') };\n    }\n  }\n\n  /** Parse \"1 Metre\", \"12 Metres\", \"10 ft\", \"3m\" into metres; null if none. */\n  function parseLengthM(title) {\n    if (!title) return null;\n    var m = /(\\d+(?:\\.\\d+)?)\\s*(m|meter|metre|meters|metres)\\b/i.exec(title);\n    if (m) return parseFloat(m[1]);\n    var f = /(\\d+(?:\\.\\d+)?)\\s*(ft|feet|foot|')/i.exec(title);\n    if (f) return round2(parseFloat(f[1]) * 0.3048);\n    return null;\n  }\n\n  /** Shortest in-stock variant that covers the run; else the longest in stock (flagged short). */\n  function pickVariantForLength(variants, runM) {\n    var pool = variants.filter(function (v) { return v.available; });\n    if (!pool.length) return { variant: null, lengthM: null };\n    var withLen = pool\n      .map(function (v) { return { v: v, len: parseLengthM(v.title) }; })\n      .filter(function (x) { return x.len !== null; })\n      .sort(function (a, b) { return a.len - b.len; });\n    if (!withLen.length) return { variant: pool[0], lengthM: null };\n    for (var i = 0; i < withLen.length; i++) {\n      if (withLen[i].len >= runM) return { variant: withLen[i].v, lengthM: withLen[i].len };\n    }\n    var longest = withLen[withLen.length - 1];\n    return { variant: longest.v, lengthM: longest.len, short: true };\n  }\n\n  var ROLE_NAME = {\n    antenna_low: 'low-gain antenna', antenna_mid: 'mid-gain antenna', antenna_high: 'high-gain antenna', antenna_directional: 'directional antenna',\n    cable_rpsma: 'LMR-400 cable (N-female to RP-SMA male)', cable_nm: 'LMR-400 cable (N-female to N-male)', window_pass: 'window pass cable', window_pass_nm: 'N-male window pass cable',\n    arrestor: 'lightning arrestor', arrestor_nf: 'lightning arrestor', adaptor_nm_nm: 'N-male to N-male adaptor', mount_indoor: 'magnetic antenna base',\n    mount_wall: 'wall bracket', mount_mast: 'mast pole', enclosure_m1: 'SenseCAP M1 outdoor enclosure',\n    enclosure_bobcat: 'Bobcat outdoor enclosure', enclosure_gateway: 'outdoor gateway enclosure',\n    hotspot_m1: 'SenseCAP M1 hotspot', hotspot_nebra: 'Nebra hotspot'\n  };\n\n  // Why each hotspot is suggested. Facts from the product listings (2026-10-16): both are US915,\n  // RP-SMA female antenna port, Ethernet or Wi-Fi, all sales final. No reward or earnings wording.\n  var HOTSPOT_WHY = {\n    hotspot_m1: 'SenseCAP M1 indoor LoRaWAN hotspot (US915). It has an RP-SMA antenna port for the cable above and connects to your router by Ethernet or Wi-Fi. Set it up with the official Helium Wallet app. All sales final.',\n    hotspot_nebra: 'Nebra ROCK Pi indoor LoRaWAN hotspot (US915). It has an RP-SMA antenna port for the cable above and connects to your router by Ethernet or Wi-Fi. Nebra hasn\\u2019t kept up its onboarding credits, so you may need to pay Helium\\u2019s onboarding fee yourself (4,000,000 DC, about USD $40) or arrange it with Nebra. All sales final.'\n  };\n\n  /** First in-stock product in a role; null when none is in stock (never suggest unavailable items). */\n  function pickProduct(catalog, role) {\n    var list = (catalog[role] || []).filter(Boolean);\n    if (!list.length) return null;\n    for (var i = 0; i < list.length; i++) if (list[i].available && firstAvailableVariant(list[i])) return list[i];\n    return null;\n  }\n\n  function firstAvailableVariant(p) {\n    return (p.variants || []).find(function (v) { return v.available; }) || null;\n  }\n\n  /**\n   * input: { location: indoor|attic|wall|roof, environment: city|suburban|rural|hilly,\n   *          heightM, runM, hotspotPlacement: inside|outside, route: wall|window,\n   *          hotspotModel: m1|gateway|bobcat|other, directional,\n   *          needHotspot: bool (customer wants us to supply one), hotspotChoice: m1|nebra }\n   * catalog: { role: [ { handle,title,url,image,available,gain?,variants:[{id,title,price,available}] } ] }\n   */\n  function recommend(input, catalog) {\n    // A hotspot we supply in an outdoor enclosure is always the SenseCAP M1: its enclosure kit is made for it.\n    var model = input.needHotspot ? 'm1' : input.hotspotModel;\n    var indoor = input.location === 'indoor';\n    // A flat panel indoors needs the N-male adaptor and an RP-SMA lead (it doesn't fit the magnetic base);\n    // without both on hand, fall back to the upright window antenna.\n    if (indoor && input.directional && !(pickProduct(catalog, 'adaptor_nm_nm') && pickProduct(catalog, 'cable_rpsma'))) {\n      input = Object.assign({}, input, { directional: false });\n    }\n    // An enclosure is for a hotspot outdoors beside the antenna, so it isn't offered for attic setups.\n    var hotspotOutside = !indoor && input.location !== 'attic' && input.hotspotPlacement === 'outside';\n    var useWindow = !indoor && !hotspotOutside && input.route === 'window';\n    var items = [];\n    var losses = []; // { label, db }\n    var chain = [];\n    var notes = [];\n    var unspecifiedLoss = null;\n\n    function add(role, reason, variant) {\n      var p = pickProduct(catalog, role);\n      if (!p) return null; // Fraser: never show out-of-stock parts; callers pick an in-stock alternative\n      var item = { role: role, product: p, variant: variant || firstAvailableVariant(p), reason: reason, quantity: 1 };\n      items.push(item);\n      return item;\n    }\n    function lose(label, db) { losses.push({ label: label, db: round2(db) }); }\n\n    // Antenna\n    var cls = chooseAntennaClass(input);\n    var ant = add(cls.role, cls.why);\n    if (!ant) {\n      var altRoles = ['antenna_mid', 'antenna_low', 'antenna_high'];\n      for (var ai = 0; ai < altRoles.length && !ant; ai++) {\n        if (altRoles[ai] !== cls.role) { cls = { role: altRoles[ai], why: cls.why }; ant = add(altRoles[ai], cls.why); }\n      }\n    }\n    var gain = ant && ant.product.gain != null ? Number(ant.product.gain) : null;\n    var directional = cls.role === 'antenna_directional';\n    chain.push(t(ant ? (directional ? 'Directional antenna (N-female)' : 'Antenna (N-male)') : 'Antenna'));\n\n    if (indoor && directional) {\n      var pc = pickProduct(catalog, 'cable_rpsma');\n      var pp = pickVariantForLength(pc.variants, BASE_CABLE_M);\n      add('adaptor_nm_nm', t('N-male to N-male adaptor. The flat panel has a female connector, so this joins it to the cable.'));\n      add('cable_rpsma', t('Short LMR-400 low-loss cable (N-female to RP-SMA-male) from the panel to your hotspot. Stand the panel at the window facing outside.'), pp.variant);\n      chain.push(t('N-male/N-male adaptor'));\n      chain.push('LMR-400 ' + fmtLen(pp.lengthM));\n      if (pp.lengthM != null) lose(fmtLen(pp.lengthM) + ' LMR-400', pp.lengthM * LOSS_DB_PER_M.lmr400);\n      lose(t('Adaptor'), CONNECTION_DB);\n      lose(t('{n} connections', { n: 2 }), 2 * CONNECTION_DB);\n    } else if (indoor) {\n      var base = add('mount_indoor', t('Indoor-only magnetic base with a built-in 2 m low-loss cable (N-female to RP-SMA-male). Place the antenna at the window with the clearest outside view.'));\n      if (base) {\n        chain.push(t('Magnetic base, 2 m LMR-200'));\n        lose(t('2 m LMR-200 (base cable)'), BASE_CABLE_M * LOSS_DB_PER_M.lmr200);\n        lose(t('{n} connections', { n: 2 }), 2 * CONNECTION_DB);\n        notes.push(t('The base cable is 2 m long, so the hotspot needs to sit within 2 m of the antenna.'));\n      } else {\n        // No magnetic base on hand: a short LMR-400 lead joins the antenna (N-male) to the hotspot (RP-SMA).\n        var ic = pickProduct(catalog, 'cable_rpsma');\n        if (ic) {\n          var ip = pickVariantForLength(ic.variants, BASE_CABLE_M);\n          add('cable_rpsma', t('Short LMR-400 low-loss cable (N-female to RP-SMA-male) from the antenna to your hotspot. Stand the antenna upright at the window with the clearest outside view.'), ip.variant);\n          chain.push('LMR-400 ' + fmtLen(ip.lengthM));\n          if (ip.lengthM != null) lose(fmtLen(ip.lengthM) + ' LMR-400', ip.lengthM * LOSS_DB_PER_M.lmr400);\n          lose(t('{n} connections', { n: 2 }), 2 * CONNECTION_DB);\n        }\n      }\n    } else {\n      var groundNote = ' ' + t('Bond its ground lug to your building\\'s grounding system per local electrical code.');\n      var rak = pickProduct(catalog, 'arrestor');\n      var laird = rak ? null : pickProduct(catalog, 'arrestor_nf');\n      // Fraser prefers no adaptor with the Laird: an N-male window pass screws straight onto it.\n      // Not possible for a directional antenna (N-female) or an enclosure (N-female bulkhead).\n      var wpNm = laird && !directional && !hotspotOutside ? pickProduct(catalog, 'window_pass_nm') : null;\n      var lairdDirect = !!wpNm;\n      if (lairdDirect) {\n        var outRunM = Math.max(input.runM - WINDOW_PASS_M, 0);\n        if (outRunM > 0) {\n          var lnm = pickProduct(catalog, 'cable_nm');\n          if (lnm) {\n            var lp = pickVariantForLength(lnm.variants, outRunM);\n            add('cable_nm', t('LMR-400 low-loss cable (N-female to N-male) from the antenna down to the arrestor where the cable enters the building.'), lp.variant);\n            chain.push('LMR-400 ' + fmtLen(lp.lengthM));\n            if (lp.lengthM != null) lose(fmtLen(lp.lengthM) + ' LMR-400', lp.lengthM * LOSS_DB_PER_M.lmr400);\n            if (lp.short) notes.push(t('Our longest cable is {len}, shorter than your outdoor run. Move the hotspot closer to the antenna, or put it outside in an enclosure beside the antenna.', { len: fmtLen(lp.lengthM) }));\n          }\n        }\n        add('arrestor_nf', t('Laird lightning surge arrestor (N-female both ends, rated 0\\u20131000 MHz). Fit it where the cable enters the building.') + groundNote);\n        chain.push(t('Laird arrestor (N-female/N-female)'));\n        lose(t('Laird arrestor (spec <0.25 dB at 1000 MHz)'), LAIRD_DB);\n        add('window_pass_nm', useWindow\n          ? t('Flat 1 m LMR-100A cable (N-male to RP-SMA-male). It screws straight onto the Laird arrestor, so no adaptor is needed, and runs under a closed window or door to your hotspot.')\n          : t('Flat 1 m LMR-100A cable (N-male to RP-SMA-male) from the arrestor through your wall entry to the hotspot. It screws straight onto the Laird arrestor, so no adaptor is needed.'));\n        chain.push(t('Window pass, 1 m (N-male to RP-SMA-male)'));\n        lose(t('1 m LMR-100A window pass'), WINDOW_PASS_M * LOSS_DB_PER_M.lmr100);\n        lose(t('{n} connections', { n: outRunM > 0 ? 3 : 2 }), (outRunM > 0 ? 3 : 2) * CONNECTION_DB);\n      } else if (laird) {\n        // Laird is N-female on both ends, so an N-male/N-male adaptor joins it to the next N-female\n        // (and a second one joins a directional antenna's N-female to the arrestor).\n        add('arrestor_nf', t('Laird lightning surge arrestor (N-female both ends, rated 0\\u20131000 MHz) for the outdoor antenna line.') + groundNote);\n        var ad = add('adaptor_nm_nm', directional\n          ? t('Two N-male to N-male adaptors: one joins the directional antenna (N-female) to the arrestor, one joins the arrestor to the cable.')\n          : t('N-male to N-male adaptor. The Laird arrestor is N-female on both ends, so this joins it to the next cable.'));\n        if (ad && directional) ad.quantity = 2;\n        if (directional) { chain.push(t('N-male/N-male adaptor')); lose(t('Adaptor'), CONNECTION_DB); }\n        chain.push(t('Laird arrestor (N-female/N-female)'));\n        lose(t('Laird arrestor (spec <0.25 dB at 1000 MHz)'), LAIRD_DB);\n        chain.push(t('N-male/N-male adaptor'));\n        lose(t('Adaptor'), CONNECTION_DB);\n      } else {\n        var arr = add('arrestor', t('Lightning arrestor (N-male to N-female) for the outdoor antenna line.') + groundNote);\n        if (arr) {\n          chain.push(t('Lightning arrestor'));\n          lose(t('Lightning arrestor (spec \\u22640.2 dB)'), ARRESTOR_DB);\n        }\n        if (directional) {\n          add('adaptor_nm_nm', t('N-male to N-male adaptor. The directional antenna has a female connector, so this joins the arrestor to the next cable.'));\n          chain.push(t('N-male/N-male adaptor'));\n          lose(t('Adaptor'), CONNECTION_DB);\n        }\n      }\n\n      if (lairdDirect) {\n        // chain already complete\n      } else if (hotspotOutside) {\n        var encRole = model === 'm1' ? 'enclosure_m1' : model === 'bobcat' ? 'enclosure_bobcat' : 'enclosure_gateway';\n        var enc = add(encRole, t('Weatherproof IP67 enclosure kit for your hotspot, with PoE injector and splitter, pole-mount kit and an antenna pigtail (N-female to RP-SMA-male), so the hotspot sits beside the antenna.'));\n        if (enc) chain.push(t('Enclosure pigtail (included)'));\n        if (model === 'other') notes.push(t('This enclosure kit fits RAK hotspots, RAK7244 and most similar gateways. Please contact us to confirm it fits your hotspot before ordering.'));\n        lose(t('{n} connections', { n: 2 }), 2 * CONNECTION_DB);\n        unspecifiedLoss = t('the enclosure\\'s included pigtail (length not specified by the manufacturer)');\n      } else if (useWindow) {\n        var outdoorRunM = Math.max(input.runM - WINDOW_PASS_M, 0);\n        if (outdoorRunM > 0) {\n          var cnm = pickProduct(catalog, 'cable_nm');\n          if (cnm) {\n            var pick = pickVariantForLength(cnm.variants, outdoorRunM);\n            add('cable_nm', t('LMR-400 low-loss cable (N-female to N-male) for the outdoor run from the arrestor to the window.'), pick.variant);\n            chain.push('LMR-400 ' + fmtLen(pick.lengthM));\n            if (pick.lengthM != null) lose(fmtLen(pick.lengthM) + ' LMR-400', pick.lengthM * LOSS_DB_PER_M.lmr400);\n            if (pick.short) notes.push(t('Our longest cable is {len}, shorter than your outdoor run. Move the hotspot closer to the antenna, or put it outside in an enclosure beside the antenna.', { len: fmtLen(pick.lengthM) }));\n          }\n        }\n        add('window_pass', t('Flat 1 m LMR-100A window pass (N-female to RP-SMA-male). It runs under a closed window or door, so you don\\'t need to drill.'));\n        chain.push(t('Window pass, 1 m'));\n        lose(t('1 m LMR-100A window pass'), WINDOW_PASS_M * LOSS_DB_PER_M.lmr100);\n        lose(t('{n} connections', { n: outdoorRunM > 0 ? 3 : 2 }), (outdoorRunM > 0 ? 3 : 2) * CONNECTION_DB);\n      } else {\n        var c = pickProduct(catalog, 'cable_rpsma');\n        if (c) {\n          var vp = pickVariantForLength(c.variants, input.runM);\n          add('cable_rpsma', t('LMR-400 low-loss cable (N-female to RP-SMA-male) from the arrestor to your hotspot.'), vp.variant);\n          chain.push('LMR-400 ' + fmtLen(vp.lengthM));\n          if (vp.lengthM != null) lose(fmtLen(vp.lengthM) + ' LMR-400', vp.lengthM * LOSS_DB_PER_M.lmr400);\n          lose(t('{n} connections', { n: 2 }), 2 * CONNECTION_DB);\n          if (vp.short) notes.push(t('Our longest cable is {len}, shorter than your {run} m run. Move the hotspot closer to the antenna, or put it outside in an enclosure beside the antenna.', { len: fmtLen(vp.lengthM), run: num(input.runM) }));\n        }\n      }\n\n      var addMount = function (role, reason) {\n        if (add(role, reason)) return;\n        var other = role === 'mount_wall' ? 'mount_mast' : 'mount_wall';\n        add(other, other === 'mount_wall' ? t('L-type wall bracket that holds the antenna away from the wall or a mast.') : t('U-shaped hoisting pole for roof, chimney or mast mounting.'));\n      };\n      if (input.location === 'attic') {\n        addMount('mount_wall', t('Wall bracket to stand the antenna off a rafter or gable wall.'));\n        notes.push(t('Metal roofing, solar panels and foil-backed insulation block radio signals. A gable-end wall is usually the clearest spot in an attic.'));\n      } else if (input.location === 'wall') {\n        addMount('mount_wall', t('L-type wall bracket that holds the antenna away from the wall.'));\n      } else {\n        addMount('mount_mast', t('U-shaped hoisting pole for roof, chimney or mast mounting.'));\n      }\n    }\n    if (input.needHotspot) {\n      var wantHs = hotspotOutside || input.hotspotChoice !== 'nebra' ? 'hotspot_m1' : 'hotspot_nebra';\n      if (hotspotOutside && input.hotspotChoice === 'nebra') notes.push(t('For a hotspot in an outdoor enclosure we suggest the SenseCAP M1, because the enclosure kit is made for it.'));\n      var hs = add(wantHs, t(HOTSPOT_WHY[wantHs]));\n      if (!hs && !hotspotOutside) {\n        var altHs = wantHs === 'hotspot_m1' ? 'hotspot_nebra' : 'hotspot_m1';\n        add(altHs, t(HOTSPOT_WHY[altHs]));\n      }\n    }\n    chain.push(t(hotspotOutside ? 'Hotspot in enclosure (RP-SMA)' : 'Hotspot (RP-SMA)'));\n\n    var totalLoss = round1(losses.reduce(function (s, l) { return s + l.db; }, 0));\n    if (totalLoss > 3) notes.push(t('Feedline loss is over 3 dB, which means less than half the hotspot\\'s power reaches the antenna. A shorter run or an outdoor enclosure would reduce it.'));\n\n    var total = items.reduce(function (s, it) {\n      return s + (it.product.available && it.variant ? Number(it.variant.price) * it.quantity : 0);\n    }, 0);\n\n    return {\n      antennaGain: gain,\n      feedlineLossDb: totalLoss,\n      powerDeliveredPct: Math.round(Math.pow(10, -totalLoss / 10) * 100),\n      losses: losses,\n      unspecifiedLoss: unspecifiedLoss,\n      netGainDb: gain == null ? null : round1(gain - totalLoss),\n      horizonKm: radioHorizonKm(input.heightM),\n      chain: chain,\n      items: items,\n      notes: notes,\n      total: round2(total)\n    };\n  }\n\n  function fmtLen(m) {\n    if (m == null) return '';\n    return num(Math.round(m * 10) / 10) + ' m';\n  }\n\n  var core = {\n    recommend: recommend,\n    radioHorizonKm: radioHorizonKm,\n    chooseAntennaClass: chooseAntennaClass,\n    parseLengthM: parseLengthM,\n    pickVariantForLength: pickVariantForLength,\n    LOSS_DB_PER_M: LOSS_DB_PER_M\n  };\n\n  if (typeof module !== 'undefined' && module.exports) {\n    module.exports = core;\n    return;\n  }\n\n  // ---------------------------------------------------------------- UI\n\n  function esc(s) {\n    return String(s == null ? '' : s).replace(/[&<>\"']/g, function (c) {\n      return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' }[c];\n    });\n  }\n\n  function money(n, currency) {\n    try {\n      // Fraser: every price says its currency (CAD), e.g. \"$5.99 CAD\".\n      // In French: \"5,99 $ CA\" (or \"5,99 $ US\"), the Canadian French style.\n      var code = currency || 'CAD';\n      if (L.lang() === 'fr') {\n        var fr = new Intl.NumberFormat('fr-CA', { style: 'currency', currency: code, currencyDisplay: 'narrowSymbol' }).format(n);\n        return /\\$/.test(fr) && code.slice(-1) === 'D' ? fr + '\\u00a0' + code.slice(0, 2) : fr + '\\u00a0' + code;\n      }\n      return new Intl.NumberFormat('en-CA', { style: 'currency', currency: code, currencyDisplay: 'narrowSymbol' }).format(n) + ' ' + code;\n    } catch (e) { return Number(n).toFixed(2) + ' ' + (currency || 'CAD'); }\n  }\n\n  // Short URL keys so a plan can be shared or bookmarked: ?loc=wall&env=suburban&h=6...\n  var PARAMS = { loc: 'location', env: 'environment', h: 'height', at: 'placement', via: 'route', run: 'run', model: 'model', own: 'own', pick: 'pick', dir: 'directional' };\n\n  function setField(f, name, value) {\n    var el = f.elements[name];\n    if (!el) return;\n    if (el.type === 'checkbox') { el.checked = value === '1'; return; }\n    if (el.length && !el.options) { // radio group\n      for (var i = 0; i < el.length; i++) if (el[i].value === value && !el[i].closest('[hidden]')) el[i].checked = true;\n      return;\n    }\n    if (el.options) { for (var j = 0; j < el.options.length; j++) if (el.options[j].value === value) el.value = value; return; }\n    if (el.type === 'range') {\n      var n = parseFloat(value);\n      if (!isNaN(n)) el.value = Math.min(Math.max(n, +el.min), +el.max);\n      return;\n    }\n  }\n\n  function applyParams(root) {\n    var f = root.querySelector('form');\n    var q;\n    try { q = new URLSearchParams(global.location.search); } catch (e) { return false; }\n    var any = false;\n    Object.keys(PARAMS).forEach(function (k) { if (q.has(k)) { setField(f, PARAMS[k], q.get(k)); any = true; } });\n    return any;\n  }\n\n  function planQuery(root) {\n    var f = root.querySelector('form');\n    var q = [];\n    Object.keys(PARAMS).forEach(function (k) {\n      var el = f.elements[PARAMS[k]];\n      if (!el) return;\n      var v = el.type === 'checkbox' ? (el.checked ? '1' : '0') : el.value;\n      if (v !== '' && v != null) q.push(k + '=' + encodeURIComponent(v));\n    });\n    return q.join('&');\n  }\n\n  function planUrl(root) {\n    var loc = global.location;\n    return loc.origin + loc.pathname + '?' + planQuery(root) + '#mnsp';\n  }\n\n  function readForm(root) {\n    var f = root.querySelector('form');\n    var get = function (n) { var el = f.elements[n]; return el ? el.value : ''; };\n    var checked = function (n) { var el = f.elements[n]; return !!(el && el.checked); };\n    return {\n      location: get('location'),\n      environment: get('environment'),\n      heightM: parseFloat(get('height')) || 3,\n      runM: parseFloat(get('run')) || 1,\n      hotspotPlacement: get('placement'),\n      route: get('route'),\n      hotspotModel: get('model'),\n      directional: checked('directional'),\n      needHotspot: get('own') === 'need',\n      hotspotChoice: get('pick')\n    };\n  }\n\n  function syncVisibility(root, input) {\n    var outdoor = input.location !== 'indoor';\n    var canMountOutside = outdoor && input.location !== 'attic';\n    var outside = canMountOutside && input.hotspotPlacement === 'outside';\n    var show = function (sel, on) { root.querySelectorAll(sel).forEach(function (el) { el.hidden = !on; }); };\n    show('[data-show=\"outdoor\"]', outdoor);\n    show('[data-show=\"outside-ok\"]', canMountOutside);\n    show('[data-show=\"hotspot-outside\"]', outside && !input.needHotspot);\n    show('[data-show=\"cable-run\"]', outdoor && !outside);\n    show('[data-show=\"need\"]', input.needHotspot);\n    var hv = root.querySelector('[data-height-value]');\n    if (hv) hv.textContent = input.heightM + ' m';\n    var rv = root.querySelector('[data-run-value]');\n    if (rv) rv.textContent = input.runM + ' m';\n  }\n\n  /** Show live prices on the hotspot choices, and hide any hotspot with no on-hand stock. */\n  function decorateHotspots(root, catalog, currency) {\n    var anyHotspot = false;\n    root.querySelectorAll('[data-hotspot-role]').forEach(function (label) {\n      var role = label.getAttribute('data-hotspot-role');\n      var p = pickProduct(catalog, role);\n      var v = p && firstAvailableVariant(p);\n      label.hidden = !v;\n      if (v) {\n        anyHotspot = true;\n        var price = label.querySelector('[data-price]');\n        if (price) price.textContent = money(v.price, currency);\n      }\n    });\n    // No hotspot on hand: drop the \"I need one\" choice entirely (Fraser: never show unavailable items).\n    var need = root.querySelector('[data-own-need]');\n    if (need) need.hidden = !anyHotspot;\n    // ...and with no hotspot to offer, the whole last step has nothing to ask.\n    var step = root.querySelector('[data-hotspot-step]');\n    if (step) step.hidden = !anyHotspot;\n    var f = root.querySelector('form');\n    if (!anyHotspot && f.elements.own) setField(f, 'own', 'have');\n    var pick = f.elements.pick;\n    if (pick && pick.length) {\n      var cur = Array.prototype.find.call(pick, function (r) { return r.checked; });\n      if (!cur || cur.closest('[hidden]')) {\n        var first = Array.prototype.find.call(pick, function (r) { return !r.closest('[hidden]'); });\n        if (first) first.checked = true;\n      }\n    }\n  }\n\n  function sceneKey(input) {\n    return [input.location, input.hotspotPlacement, input.route, input.environment].join('|');\n  }\n\n  /**\n   * Swap in the new drawing. A different scene (location, surroundings, hotspot placement, cable\n   * route) cross-fades over the old one; any other click redraws the cable and callouts in place.\n   * Dragging a slider just updates, so it stays smooth.\n   */\n  function drawDiagram(root, input, r, animate) {\n    var host = root.querySelector('[data-mnsp-bp]');\n    if (!host || !global.MNSPDiagram) return;\n    var tmp = document.createElement('div');\n    tmp.innerHTML = global.MNSPDiagram.draw(input, r);\n    var next = tmp.firstChild;\n    var key = sceneKey(input);\n    var sceneChanged = root.__mnspScene !== key;\n    root.__mnspScene = key;\n    var prev = host.querySelectorAll('svg');\n    if (!animate || !prev.length) {\n      prev.forEach(function (el) { el.remove(); });\n      if (animate) next.classList.add('is-redrawn');\n      host.appendChild(next);\n      return;\n    }\n    if (sceneChanged) {\n      // Keep only the newest old drawing underneath, then fade the new one in over it.\n      for (var i = 0; i < prev.length - 1; i++) prev[i].remove();\n      var under = prev[prev.length - 1];\n      under.classList.remove('is-over');\n      next.classList.add('is-entering', 'is-over');\n      host.appendChild(next);\n      next.addEventListener('animationend', function done(e) {\n        if (e.target !== next) return; // the fade of the whole drawing, not the cable or numbers\n        next.removeEventListener('animationend', done);\n        if (under.parentNode) under.remove();\n        next.classList.remove('is-over');\n      });\n    } else {\n      prev.forEach(function (el) { el.remove(); });\n      next.classList.add('is-redrawn');\n      host.appendChild(next);\n    }\n  }\n\n  function render(root, catalog, settings, animate) {\n    var input = readForm(root);\n    syncVisibility(root, input);\n    var r = recommend(input, catalog);\n    drawDiagram(root, input, r, animate);\n    var out = root.querySelector('[data-mnsp-result]');\n    var currency = settings.currency;\n\n    if (settings.syncUrl && global.history && global.history.replaceState) {\n      try { global.history.replaceState(global.history.state, '', global.location.pathname + '?' + planQuery(root) + global.location.hash); } catch (e) { /* ignore */ }\n    }\n\n    var rows = r.items.map(function (it, i) {\n      var p = it.product;\n      var vTitle = it.variant && it.variant.title && it.variant.title !== 'Default Title' ? esc(it.variant.title) : '';\n      var gainTag = p.gain != null ? '<span class=\"mnsp-tag\">' + num(p.gain) + ' dBi</span>' : '';\n      return '<li class=\"mnsp-item\" data-n=\"' + (i + 1) + '\">' +\n        '<label class=\"mnsp-item__check\">' +\n          '<input type=\"checkbox\" data-item=\"' + i + '\" checked aria-label=\"' + esc(t('Include {product}', { product: p.title })) + '\">' +\n          '<span class=\"mnsp-num\" aria-hidden=\"true\">' + (i + 1) + '</span>' +\n        '</label>' +\n        (p.image ? '<img class=\"mnsp-item__img\" src=\"' + esc(p.image) + '\" alt=\"\" loading=\"lazy\" width=\"64\" height=\"64\">' : '<span class=\"mnsp-item__img\" aria-hidden=\"true\"></span>') +\n        '<div class=\"mnsp-item__body\">' +\n          '<a class=\"mnsp-item__title\" href=\"' + esc(p.url) + '\">' + esc(p.title) + '</a>' + gainTag +\n          (vTitle ? '<span class=\"mnsp-item__variant\">' + vTitle + '</span>' : '') +\n          '<p class=\"mnsp-item__why\">' + esc(it.reason) + '</p>' +\n        '</div>' +\n        '<div class=\"mnsp-item__price\">' + (it.quantity > 1 ? it.quantity + ' \u00D7 ' : '') + money(it.variant.price, currency) + '</div>' +\n      '</li>';\n    }).join('');\n\n    var lossRows = r.losses.map(function (l) {\n      return '<tr><td>' + esc(l.label) + '</td><td>' + num(l.db, 2) + ' dB</td></tr>';\n    }).join('');\n    var notes = r.notes.map(function (n) { return '<li>' + esc(n) + '</li>'; }).join('');\n    var lossValue = num(r.feedlineLossDb) + ' dB' + (r.unspecifiedLoss ? '*' : '');\n\n    out.innerHTML =\n      '<div class=\"mnsp-stats\" role=\"group\" aria-label=\"' + esc(t('Calculated figures')) + '\">' +\n        '<div class=\"mnsp-stat\"><span class=\"mnsp-stat__value\">' + (r.antennaGain == null ? '\u2013' : num(r.antennaGain) + ' dBi') + '</span><span class=\"mnsp-stat__label\">' + t('Antenna gain (manufacturer spec)') + '</span></div>' +\n        '<div class=\"mnsp-stat\"><span class=\"mnsp-stat__value\">' + lossValue + '</span><span class=\"mnsp-stat__label\">' + t('Feedline loss') + '</span></div>' +\n        '<div class=\"mnsp-stat\"><span class=\"mnsp-stat__value\">' + num(r.horizonKm) + ' km</span><span class=\"mnsp-stat__label\">' + t('Line-of-sight horizon') + '</span></div>' +\n      '</div>' +\n      '<p class=\"mnsp-fine\">' + esc(t('The horizon is the furthest an antenna at {h} m can see a device 1.5 m off the ground over perfectly smooth terrain. It is a geometric limit, not a coverage estimate. Buildings, trees and terrain usually limit real-world range to much less.', { h: num(input.heightM) })) +\n        (r.unspecifiedLoss ? ' ' + esc(t('*Plus {unspecified}.', { unspecified: r.unspecifiedLoss })) : '') + '</p>' +\n      (notes ? '<ul class=\"mnsp-notes\">' + notes + '</ul>' : '') +\n      '<h3 class=\"mnsp-h3\">' + t('Your parts') + ' <span class=\"mnsp-h3__aside\">' + t('numbers match the drawing') + '</span></h3>' +\n      (rows ? '<ul class=\"mnsp-items\">' + rows + '</ul>' : '<p class=\"mnsp-fine\">' + t('Browse our antennas and cables for this setup.') + '</p>') +\n      '<div class=\"mnsp-cartbar\">' +\n        '<div><span class=\"mnsp-total\" data-total>' + money(r.total, currency) + '</span><span class=\"mnsp-fine\"> ' + t('Untick anything you already own.') + '</span></div>' +\n        '<button type=\"button\" class=\"mnsp-btn\" data-add' + (r.items.length ? '' : ' disabled') + '>' + t('Add selected to cart') + '</button>' +\n      '</div>' +\n      '<p class=\"mnsp-status\" role=\"status\" aria-live=\"polite\" data-status></p>' +\n      '<div class=\"mnsp-share\"><button type=\"button\" class=\"mnsp-link\" data-share>' + t('Copy a link to this plan') + '</button><span class=\"mnsp-fine\">' + t('Send it to your installer, or save it for later.') + '</span></div>' +\n      '<details class=\"mnsp-math\"><summary>' + t('How it connects and how we calculate') + '</summary>' +\n        '<ol class=\"mnsp-chain\">' + r.chain.map(function (c) { return '<li>' + esc(c) + '</li>'; }).join('') + '</ol>' +\n        '<table class=\"mnsp-loss\"><tbody>' + lossRows + '<tr class=\"mnsp-loss__total\"><td>' + t('Feedline loss') + '</td><td>' + num(r.feedlineLossDb, 1) + ' dB</td></tr><tr><td>' + t('Share of transmit power reaching the antenna') + (r.unspecifiedLoss ? ' ' + t('(before the pigtail)') : '') + '</td><td>\u2248' + r.powerDeliveredPct + (L.lang() === 'fr' ? '\\u00a0%' : '%') + '</td></tr></tbody></table>' +\n        '<p>' + esc(t('Cable loss is the manufacturer\\'s typical attenuation at 900 MHz (Times Microwave LMR-400 12.8 dB/100 m, LMR-200 32.6 dB/100 m, LMR-100A 74.9 dB/100 m), multiplied by the cable length. The arrestor uses its rated loss (RAKwireless \u22640.2 dB, Laird under 0.25 dB at 1000 MHz). Each connection or adaptor gets an allowance of 0.1 dB.')) + '</p>' +\n        '<p>' + (L.lang() === 'fr'\n          ? 'L\\u2019horizon en visibilit\\u00e9 directe est d = 4,12 \\u00d7 (\\u221ah<sub>antenne</sub> + \\u221a1,5) km, la formule standard de l\\u2019horizon radio avec une r\\u00e9fraction de 4/3 de la Terre.'\n          : 'The line-of-sight horizon is d = 4.12 \u00D7 (\u221Ah<sub>antenna</sub> + \u221A1.5) km, the standard radio-horizon formula with 4/3-Earth refraction.') + '</p>' +\n      '</details>';\n\n    out.querySelectorAll('img.mnsp-item__img').forEach(function (img) {\n      img.addEventListener('error', function () {\n        var ph = document.createElement('span');\n        ph.className = 'mnsp-item__img';\n        ph.setAttribute('aria-hidden', 'true');\n        img.replaceWith(ph);\n      });\n    });\n\n    // Point at a part in the drawing when its row is hovered or focused, and dim parts the customer unticks.\n    var svgs = root.querySelectorAll('[data-mnsp-bp] svg');\n    var svg = svgs[svgs.length - 1];\n    function callout(n) { return svg ? svg.querySelector('.bp-callout[data-n=\"' + n + '\"]') : null; }\n    out.querySelectorAll('.mnsp-item').forEach(function (li) {\n      var n = li.getAttribute('data-n');\n      var on = function () { var c = callout(n); if (c) c.classList.add('is-hot'); };\n      var off = function () { var c = callout(n); if (c) c.classList.remove('is-hot'); };\n      li.addEventListener('mouseenter', on); li.addEventListener('mouseleave', off);\n      li.addEventListener('focusin', on); li.addEventListener('focusout', off);\n    });\n\n    function selected() {\n      return r.items.filter(function (it, i) {\n        var cb = out.querySelector('input[data-item=\"' + i + '\"]');\n        return cb && cb.checked && it.variant;\n      });\n    }\n\n    out.querySelectorAll('input[data-item]').forEach(function (cb) {\n      cb.addEventListener('change', function () {\n        var n = Number(cb.getAttribute('data-item')) + 1;\n        var c = callout(n);\n        if (c) c.classList.toggle('is-owned', !cb.checked);\n        var t = selected().reduce(function (s, it) { return s + Number(it.variant.price) * it.quantity; }, 0);\n        out.querySelector('[data-total]').textContent = money(t, currency);\n        out.querySelector('[data-add]').disabled = selected().length === 0;\n      });\n    });\n\n    out.querySelector('[data-share]').addEventListener('click', function () {\n      var url = planUrl(root);\n      var status = out.querySelector('[data-status]');\n      var done = function () { status.textContent = t('Link copied. Anyone who opens it sees this plan.'); };\n      if (global.navigator && global.navigator.clipboard && global.navigator.clipboard.writeText) {\n        global.navigator.clipboard.writeText(url).then(done, function () { status.textContent = url; });\n      } else {\n        status.textContent = url;\n      }\n    });\n\n    out.querySelector('[data-add]').addEventListener('click', function () {\n      var btn = this;\n      var picked = selected();\n      if (!picked.length) return;\n      var status = out.querySelector('[data-status]');\n      var rootPath = global.Shopify && global.Shopify.routes ? global.Shopify.routes.root : '/';\n      btn.disabled = true;\n      status.textContent = t('Adding to cart\u2026');\n      var body = { items: picked.map(function (it) { return { id: it.variant.id, quantity: it.quantity }; }) };\n      var addFn = settings.addToCart || function (payload) {\n        return fetch(rootPath + 'cart/add.js', {\n          method: 'POST',\n          headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n          body: JSON.stringify(payload)\n        }).then(function (res) {\n          return res.json().then(function (j) {\n            if (!res.ok) throw new Error(j.description || t('Could not add to cart'));\n            return j;\n          });\n        });\n      };\n      Promise.resolve(addFn(body)).then(function (resp) {\n        status.textContent = L.lang() === 'fr'\n          ? t('Added {n} item(s) to your cart.', { n: picked.length })\n          : 'Added ' + picked.length + ' item' + (picked.length > 1 ? 's' : '') + ' to your cart.';\n        // Dawn's pub/sub cart event (cart drawer and bubble listen to it).\n        if (typeof global.publish === 'function' && global.PUB_SUB_EVENTS) {\n          global.publish(global.PUB_SUB_EVENTS.cartUpdate, { source: 'mn-setup-planner', cartData: resp });\n        }\n        document.dispatchEvent(new CustomEvent('cart:update', { bubbles: true, detail: { source: 'mn-setup-planner', data: resp } }));\n        if (settings.goToCart) global.location.href = rootPath + 'cart';\n        else btn.disabled = false;\n      }).catch(function (err) {\n        status.textContent = t('{error}. Please try again, or add the items from their product pages.', { error: err.message });\n        btn.disabled = false;\n      });\n    });\n  }\n\n  function mount(root) {\n    if (root.__mnsp) return;\n    root.__mnsp = true;\n    L.setLang(root.getAttribute('data-locale') || document.documentElement.lang);\n    var catEl = root.querySelector('script[data-mnsp-catalog]');\n    var catalog = {};\n    try { catalog = catEl ? JSON.parse(catEl.textContent) : {}; } catch (e) { catalog = {}; }\n    var designMode = !!(global.Shopify && global.Shopify.designMode);\n    var settings = {\n      currency: root.getAttribute('data-currency') || 'CAD',\n      goToCart: root.getAttribute('data-go-to-cart') === 'true',\n      syncUrl: !designMode && root.getAttribute('data-sync-url') !== 'false',\n      addToCart: global.__mnspAddToCart // preview hook only\n    };\n    var form = root.querySelector('form');\n    applyParams(root);\n    decorateHotspots(root, catalog, settings.currency);\n    // Sliders redraw live while dragging (no animation); every click on a choice animates.\n    form.addEventListener('input', function (e) { if (e.target.type === 'range') render(root, catalog, settings, false); });\n    form.addEventListener('change', function (e) { render(root, catalog, settings, e.target.type !== 'range'); });\n    form.addEventListener('submit', function (e) { e.preventDefault(); });\n    render(root, catalog, settings, true);\n  }\n\n  function init() { document.querySelectorAll('[data-mnsp]').forEach(mount); }\n  global.MNSetupPlanner = core;\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);\n  else init();\n  document.addEventListener('shopify:section:load', init);\n})(typeof window !== 'undefined' ? window : globalThis);\n\n\n  } catch(e) { console.error(e); }\n})();\n})();\n"],
  "mappings": "CAAC,UAAW,CACV,IAAI,aAAe,CAAC,GACnB,UAAW,CACV,QAAQ,EAAI,EAAG,EAAI,SAAS,eAAe,iBAAiB,EAAE,aAAa,eAAe,EAAE,MAAM,GAAG,EAAG,EAAI,EAAE,OAAQ,IACpH,aAAa,EAAE,CAAC,CAAC,EAAI,EACvB,GAAG,GACF,UAAW,CACd,GAAK,aAAa,OAClB,GAAI,CAEJ,MAAM,qBAAqB,WAAY,CACrC,aAAc,CACZ,MAAM,EACN,KAAK,gBAAkB,KAAK,gBAAgB,KAAK,IAAI,CACvD,CAEA,mBAAoB,CAClB,KAAK,OAAS,SAAS,cAAc,iBAAiB,EACtD,KAAK,iBAAmB,OAAO,WAAW,oBAAoB,EAC9D,KAAK,qBACH,KAAK,aAAa,kBAAkB,IAAM,UAC1C,KAAK,aAAa,kBAAkB,IAAM,mBAC5C,KAAK,aAAe,CAAC,EAErB,KAAK,gBAAgB,EAErB,KAAK,iBAAiB,iBAAiB,SAAU,KAAK,eAAe,EAEjE,KAAK,sBACP,KAAK,OAAO,UAAU,IAAI,+BAA+B,EAG3D,KAAK,iBAAmB,EACxB,KAAK,cAAgB,GACrB,KAAK,mBAAqB,KAAK,iBAAiB,mBAAmB,EAEnE,KAAK,gBAAkB,KAAK,SAAS,KAAK,IAAI,EAC9C,KAAK,qBAAuB,IAAO,KAAK,cAAgB,GAExD,KAAK,iBAAiB,sBAAuB,KAAK,oBAAoB,EACtE,OAAO,iBAAiB,SAAU,KAAK,gBAAiB,EAAK,EAE7D,KAAK,eAAe,CACtB,CAEA,iBAAkB,CAChB,SAAS,gBAAgB,MAAM,YAAY,kBAAmB,GAAG,KAAK,OAAO,YAAY,IAAI,CAC/F,CAEA,sBAAuB,CACrB,KAAK,iBAAiB,oBAAoB,SAAU,KAAK,eAAe,EACxE,KAAK,oBAAoB,sBAAuB,KAAK,oBAAoB,EACzE,OAAO,oBAAoB,SAAU,KAAK,eAAe,CAC3D,CAEA,gBAAiB,CACA,IAAI,qBAAqB,CAAC,QAASA,YAAa,CAC7D,KAAK,aAAe,QAAQ,CAAC,EAAE,iBAC/BA,UAAS,WAAW,CACtB,CAAC,EAEQ,QAAQ,KAAK,MAAM,CAC9B,CAEA,UAAW,CACT,MAAM,UAAY,OAAO,aAAe,SAAS,gBAAgB,UAEjE,GAAI,EAAC,GAAG,KAAK,kBAAkB,EAAE,KAAM,kBAAqB,iBAAiB,MAAM,EAEnF,IAAI,UAAY,KAAK,kBAAoB,UAAY,KAAK,aAAa,OAAQ,CAE7E,GADA,KAAK,OAAO,UAAU,IAAI,sBAAsB,EAC5C,KAAK,YAAa,OACtB,sBAAsB,KAAK,KAAK,KAAK,IAAI,CAAC,CAC5C,MAAW,UAAY,KAAK,kBAAoB,UAAY,KAAK,aAAa,QAC5E,KAAK,OAAO,UAAU,IAAI,sBAAsB,EAC3C,KAAK,eAGR,OAAO,aAAa,KAAK,WAAW,EAEpC,KAAK,YAAc,WAAW,IAAM,CAClC,KAAK,cAAgB,EACvB,EAAG,EAAE,EAEL,sBAAsB,KAAK,KAAK,KAAK,IAAI,CAAC,GAR1C,sBAAsB,KAAK,OAAO,KAAK,IAAI,CAAC,GAUrC,WAAa,KAAK,aAAa,MACxC,KAAK,OAAO,UAAU,OAAO,sBAAsB,EACnD,sBAAsB,KAAK,MAAM,KAAK,IAAI,CAAC,GAG7C,KAAK,iBAAmB,UAC1B,CAEA,MAAO,CACD,KAAK,uBACT,KAAK,OAAO,UAAU,IAAI,gCAAiC,+BAA+B,EAC1F,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACxB,CAEA,QAAS,CACH,KAAK,uBACT,KAAK,OAAO,UAAU,IAAI,gCAAiC,SAAS,EACpE,KAAK,OAAO,UAAU,OAAO,+BAA+B,EAC9D,CAEA,OAAQ,CACF,KAAK,sBACT,KAAK,OAAO,UAAU,OAAO,gCAAiC,gCAAiC,SAAS,CAC1G,CAEA,qBAAsB,CACpB,KAAK,YAAc,KAAK,aAAe,KAAK,OAAO,iBAAiB,aAAa,EACjF,KAAK,YAAY,QAAS,YAAe,WAAW,MAAM,CAAC,CAC7D,CAEA,kBAAmB,CACjB,KAAK,aAAe,KAAK,cAAgB,KAAK,OAAO,iBAAiB,eAAe,EACrF,KAAK,aAAa,QAAS,aAAgB,YAAY,MAAM,EAAK,CAAC,CACrE,CACF,CAMA,SAAS,iBACP,OACC,OAAU,CACT,GAAI,EAAE,MAAM,kBAAkB,cAAgB,CAAC,MAAM,OAAO,QAAQ,iBAAiB,EAAG,OAExF,MAAM,OAAS,KAAK,IAAI,EAAG,KAAK,MAAM,MAAM,OAAO,sBAAsB,EAAE,MAAM,CAAC,EAClF,MAAM,OAAO,MAAM,YAAY,uBAAwB,GAAG,MAAM,IAAI,CACtE,EACA,EACF,EAEA,eAAe,OAAO,gBAAiB,YAAY,CAEnD,OAAQ,EAAG,CAAE,QAAQ,MAAM,CAAC,CAAG,CACjC,GAAG,GAEF,UAAW,CACV,GAAI,GAAC,aAAa,kBAAkB,GAAK,CAAC,QAAQ,YAClD,GAAI,EASL,SAAU,OAAQ,CACjB,aAEA,IAAI,GAAK,CAAC,6BAA6B,2BAAqB,sBAAsB,gDAAoC,MAAQ,UAAU,eAAe,mBAAgB,sBAAsB,uBAAoB,oBAAoB,0BAAuB,aAAa,qBAAqB,wBAAwB,2BAA2B,mBAAmB,yBAAmB,mBAAmB,yBAAsB,kFAAkF,yHAAgH,2BAA2B,yCAAmC,kDAAkD,4DAAyD,8BAA8B,6BAAuB,0CAA0C,6DAAiD,6CAA6C,uEAAqD,6BAA6B,8BAA2B,uCAAuC,0CAA0C,iBAAiB,QAAQ,iCAAiC,wCAAkC,kCAAkC,iCAAiC,sCAAsC,kDAAyC,uCAAuC,qDAAkD,6CAA6C,sDAAgD,wPAAwP,qUAAgT,2BAA2B,6BAAuB,iCAAiC,gDAA6C,qBAAqB,uBAAoB,mCAAmC,oDAAiD,gBAAgB,oBAAoB,wBAAwB,mCAAgC,mPAAmP,mWAAyT,uBAAuB,uBAAuB,8EAA8E,wGAA4F,aAAa,gBAAa,4BAA4B,4CAAsC,oBAAoB,oBAAoB,iDAAiD,mEAAgE,mCAAmC,kDAAsC,uBAAuB,oCAAiC,2BAA2B,4BAA4B,mDAAmD,mEAAgE,uCAAuC,wCAAqC,+CAA+C,2DAAwD,uBAAuB,6BAA0B,gVAA2U,sYAAyW,6IAAgI,2KAAwJ,mDAAmD,2DAAwD,uBAAkB,wBAAmB,kCAAkC,iDAA2C,wBAAwB,iCAAiC,wEAAwE,oFAAiF,+MAA+M,gSAAqQ,qKAAqK,mMAA6L,0IAA0I,wLAA4K,mIAAmI,mLAAoK,0JAA0J,kOAAgN,6LAA6L,2PAAyO,sGAAsG,yHAA6G,yHAAyH,4JAA0I,mGAAmG,iIAAwH,0HAA0H,8KAA+J,kGAAkG,4HAA6G,uIAAuI,gLAAqJ,0JAA0J,yOAAkM,qFAAqF,yGAAgG,mKAAmK,mNAAqL,qFAAqF,yIAAuH,yHAAyH,sJAA8H,2JAA2J,4MAAoL,2JAA2J,0MAAqL,0HAAqH,8IAAyH,gLAAgL,iNAA4L,iLAAiL,qMAAsL,2GAAsG,oHAAwG,oIAAoI,+JAAgJ,6GAA6G,wJAAmI,wEAAwE,+EAAsE,0HAA0H,wJAAyI,6LAA6L,sPAA2N,8IAA8I,kNAAyM,mGAAmG,iIAA4G,8HAA8H,kKAA0I,sFAAsF,wGAAyF,2EAA2E,oFAA2E,6DAA6D,iFAA2E,gEAAgE,4EAAyE,yIAAyI,sMAA0L,iEAAiE,qEAA+D,8GAA8G,0IAA2H,yJAAyJ,sLAAoK,kNAAkN,iQAAwP,iCAAiC,qCAAqC,mBAAmB,sBAAmB,QAAU,UAAU,wBAAwB,iCAA2B,gBAAgB,gBAAgB,QAAU,aAAa,kBAAkB,iBAAiB,6BAA6B,qCAAkC,2BAA2B,uCAAoC,qCAAqC,yCAAyC,6CAA6C,sDAAgD,2CAA2C,wDAA4C,mBAAmB,wBAAqB,2BAA2B,mCAAgC,qBAAqB,aAAa,yCAAoC,sCAA8B,+BAA+B,yCAAmC,gCAAgC,sCAAmC,mBAAmB,mBAAmB,OAAS,UAAU,QAAU,UAAU,sBAAsB,gDAAoC,MAAQ,UAAU,eAAe,mBAAgB,cAAc,gBAAa,aAAa,qBAAqB,iBAAiB,0BAA0B,mBAAmB,yBAAmB,kBAAkB,wBAAqB,8FAA8F,mHAA0G,UAAU,UAAU,4UAAkU,sZAAsX,EAC1xkB,CAAC,IAAM,OAAO,SAAY,aAAY,GAAK,QAAQ,WAAW,EAAE,SAEpE,IAAI,KAAO,KAEX,SAAS,QAAQ,KAAM,CAAE,KAAO,OAAO,KAAK,MAAQ,EAAE,EAAI,KAAO,IAAM,CACvE,SAAS,SAAU,CAAE,OAAO,IAAM,CAElC,SAAS,EAAE,EAAG,KAAM,CAClB,IAAI,IAAM,OAAS,MAAQ,IAAM,GAAG,CAAC,GAAK,KAAO,GAAG,CAAC,EAAI,EACzD,OAAI,OAAM,IAAM,IAAI,QAAQ,aAAc,SAAU,EAAG,EAAG,CAAE,OAAO,KAAK,KAAO,KAAK,CAAC,EAAI,CAAG,CAAC,GACtF,GACT,CAGA,SAAS,IAAI,EAAG,OAAQ,CACtB,IAAI,KAAO,QAAU,KAAO,CAAE,sBAAuB,CAAE,EAAI,CAAE,sBAAuB,OAAQ,sBAAuB,MAAO,EAC1H,GAAI,CAAE,OAAO,OAAO,CAAC,EAAE,eAAe,OAAS,KAAO,QAAU,QAAS,IAAI,CAAG,MAAY,CAAE,OAAO,OAAO,CAAC,CAAG,CAClH,CAEA,IAAI,IAAM,CAAE,EAAM,IAAU,QAAkB,KAAM,OAAQ,EACxD,OAAO,OAAW,KAAe,OAAO,QAAS,OAAO,QAAU,IACjE,OAAO,SAAW,GACzB,GAAG,OAAO,OAAW,IAAc,OAAS,UAAU,GAerD,SAAU,OAAQ,CACjB,aAEA,IAAI,EAAI,OAAO,OAAW,KAAe,OAAO,QAAU,QAAQ,WAAW,EAAI,OAAO,SACpF,EAAI,EAAE,EAEN,EAAI,IAAK,EAAI,IAEjB,SAAS,EAAE,EAAG,CAAE,OAAO,KAAK,MAAM,EAAI,EAAE,EAAI,EAAI,CAChD,SAAS,IAAI,EAAG,CACd,OAAO,OAAO,GAAY,EAAM,EAAE,QAAQ,WAAY,SAAU,EAAG,CACjE,MAAO,CAAE,IAAK,QAAS,IAAK,OAAQ,IAAK,OAAQ,IAAK,SAAU,IAAK,OAAQ,EAAE,CAAC,CAClF,CAAC,CACH,CACA,SAAS,KAAK,GAAI,GAAI,GAAI,GAAI,IAAK,CAAE,MAAO,aAAe,EAAE,EAAE,EAAI,SAAW,EAAE,EAAE,EAAI,SAAW,EAAE,EAAE,EAAI,SAAW,EAAE,EAAE,EAAI,aAAe,KAAO,QAAU,KAAO,CACnK,SAAS,KAAK,EAAG,IAAK,MAAO,CAAE,MAAO,YAAc,EAAI,aAAe,KAAO,QAAU,KAAO,OAAS,IAAM,IAAM,CAEpH,SAAS,IAAI,EAAG,KAAM,CACpB,MAAO,YAAc,EAAI,uCAAyC,KAAO,WAAa,IAAM,OACzF,KAAO,GAAK,YAAc,EAAI,0BACnC,CACA,SAAS,KAAK,EAAG,EAAG,EAAG,EAAG,IAAK,GAAI,CAAE,MAAO,YAAc,EAAE,CAAC,EAAI,QAAU,EAAE,CAAC,EAAI,YAAc,EAAE,CAAC,EAAI,aAAe,EAAE,CAAC,EAAI,KAAO,GAAK,QAAU,GAAK,IAAM,IAAM,YAAc,KAAO,QAAU,KAAO,CAC1M,SAAS,OAAO,GAAI,GAAI,EAAG,IAAK,CAAE,MAAO,eAAiB,EAAE,EAAE,EAAI,SAAW,EAAE,EAAE,EAAI,QAAU,EAAI,aAAe,KAAO,QAAU,KAAO,CAC1I,SAAS,KAAK,EAAG,EAAG,EAAG,IAAK,OAAQ,CAAE,MAAO,YAAc,EAAE,CAAC,EAAI,QAAU,EAAE,CAAC,EAAI,aAAe,KAAO,QAAU,KAAO,OAAS,iBAAmB,OAAS,IAAM,IAAM,IAAM,IAAI,CAAC,EAAI,SAAW,CACrM,SAAS,KAAK,IAAK,CAAE,OAAO,IAAI,IAAI,SAAU,EAAG,EAAG,CAAE,OAAQ,EAAI,IAAM,KAAO,EAAE,EAAE,CAAC,CAAC,EAAI,IAAM,EAAE,EAAE,CAAC,CAAC,CAAG,CAAC,EAAE,KAAK,GAAG,CAAG,CAKtH,SAAS,SAAS,IAAK,GAAI,GAAI,QAAS,EAAG,CACzC,EAAI,GAAK,EACT,IAAI,IAAM,CAAC,EACP,KAAO,GAAK,GAChB,GAAI,MAAQ,OAIV,QAHI,GAAK,CAAC,GAAI,IAAK,GAAI,IAAK,GAAI,IAAK,GAAI,EAAE,EACvC,EAAI,KAAK,IAAI,EAAG,KAAK,MAAM,MAAQ,GAAK,EAAE,CAAC,EAC3C,GAAK,KAAO,EACP,EAAI,EAAG,EAAI,EAAG,IAAK,CAC1B,IAAI,GAAK,GAAG,EAAI,GAAG,MAAM,EAAI,EACzB,GAAK,GAAK,EAAI,GAAK,EACvB,IAAI,KAAK,KAAK,GAAI,QAAU,GAAI,GAAK,EAAG,GAAI,QAAQ,CAAC,EACrD,QAAS,GAAK,QAAU,GAAK,GAAK,EAAG,GAAK,QAAU,EAAI,EAAG,IAAM,GAAK,EACpE,IAAI,KAAK,KAAK,GAAK,EAAG,GAAI,GAAK,GAAK,GAAI,GAAI,iBAAiB,CAAC,CAElE,SACS,MAAQ,WAEjB,QADI,KAAO,GAAK,EACP,GAAK,GAAK,EAAG,GAAK,GAAK,EAAI,GAAI,IAAM,KAAM,CAClD,IAAI,EAAI,GAAK,EAAG,EAAI,GAAK,EACzB,IAAI,KAAK,KAAK,KAAK,CAAC,CAAC,GAAI,OAAO,EAAG,CAAC,GAAI,QAAU,CAAC,EAAG,CAAC,GAAK,EAAI,EAAG,QAAU,EAAI,GAAK,CAAC,EAAG,CAAC,GAAK,EAAG,QAAU,CAAC,EAAG,CAAC,GAAK,EAAG,OAAO,EAAG,CAAC,GAAI,OAAO,CAAC,CAAC,EAAG,QAAQ,CAAC,EAC9J,IAAI,KAAK,KAAK,GAAK,EAAI,IAAM,QAAU,GAAK,EAAG,EAAI,IAAM,GAAK,EAAG,QAAQ,CAAC,EAC1E,IAAI,GAAK,GAAK,EAAI,GAAK,EACnB,GAAK,GAAK,EAAI,KAChB,IAAI,KAAK,KAAK,GAAI,QAAS,GAAI,QAAU,GAAK,EAAG,QAAQ,CAAC,EAC1D,IAAI,KAAK,OAAO,GAAI,QAAU,GAAK,EAAG,GAAK,EAAG,QAAQ,CAAC,EAE3D,SACS,MAAQ,QAAS,CAC1B,IAAI,KAAK,KAAK,GAAI,QAAU,EAAG,GAAI,QAAU,EAAG,iBAAiB,CAAC,EAClE,QAAS,GAAK,GAAK,EAAG,GAAK,GAAI,IAAM,GAAK,EAAG,IAAI,KAAK,KAAK,GAAI,QAAS,GAAI,QAAU,GAAK,EAAG,QAAQ,CAAC,EACvG,IAAI,KAAK,KAAK,GAAI,QAAU,EAAI,EAAG,GAAI,QAAU,EAAI,EAAG,QAAQ,CAAC,EACjE,IAAI,IAAM,GAAK,KAAO,IAClB,IAAM,GAAK,EAAI,KACjB,IAAI,KAAK,KAAK,KAAK,CAAC,CAAC,IAAK,OAAO,EAAG,CAAC,IAAK,QAAU,GAAK,CAAC,EAAG,CAAC,IAAM,GAAK,EAAG,QAAU,GAAK,CAAC,EAAG,CAAC,IAAM,GAAK,EAAG,QAAU,GAAK,CAAC,EAAG,CAAC,IAAM,GAAK,EAAG,OAAO,CAAC,CAAC,EAAG,QAAQ,CAAC,EACrK,IAAI,KAAK,KAAK,IAAM,GAAK,EAAG,QAAU,GAAK,EAAG,GAAK,EAAG,GAAK,EAAG,SAAU,CAAC,CAAC,EAE9E,MAAW,MAAQ,UACjB,IAAI,KAAK,KAAK,IAAM,EAAE,EAAE,EAAI,IAAM,EAAE,OAAO,EAAI,MAAQ,EAAE,GAAK,KAAO,GAAI,EAAI,IAAM,EAAE,QAAU,IAAM,CAAC,EAAI,IAAM,EAAE,GAAK,KAAO,EAAG,EAAI,IAAM,EAAE,QAAU,GAAK,CAAC,EAAI,MAAQ,EAAE,EAAE,EAAI,IAAM,EAAE,QAAU,GAAK,CAAC,EAAG,QAAQ,CAAC,EACrN,IAAI,KAAK,KAAK,IAAM,EAAE,GAAK,KAAO,GAAI,EAAI,IAAM,EAAE,OAAO,EAAI,MAAQ,EAAE,GAAK,KAAO,EAAG,EAAI,IAAM,EAAE,QAAU,GAAK,CAAC,EAAI,IAAM,EAAE,EAAE,EAAI,IAAM,EAAE,QAAU,GAAK,CAAC,EAAG,iBAAiB,CAAC,GAEnL,OAAO,IAAI,KAAK,EAAE,CACpB,CAIA,SAAS,aAAa,EAAG,MAAO,YAAa,CAC3C,OAAI,YACK,KAAK,EAAI,EAAG,MAAQ,GAAI,GAAI,GAAI,gBAAiB,CAAC,EACvD,KAAK,EAAI,EAAG,MAAQ,GAAI,EAAI,EAAG,MAAQ,EAAG,eAAe,EACzD,KAAK,KAAO,EAAI,IAAM,KAAO,MAAQ,IAAM,cAAgB,EAAI,IAAM,KAAO,MAAQ,IAAM,aAAe,EAAI,IAAM,KAAO,MAAQ,IAAM,UAAW,eAAe,EAE/J,KAAK,EAAI,EAAG,MAAQ,GAAI,EAAG,GAAI,gBAAiB,CAAC,EAAI,KAAK,EAAI,IAAK,MAAQ,EAAG,EAAG,EAAG,MAAM,CACnG,CAGA,SAAS,WAAW,EAAG,MAAO,CAC5B,OAAO,KAAK,EAAI,GAAI,MAAQ,GAAI,GAAI,GAAI,gBAAiB,CAAC,EAAI,KAAK,EAAI,EAAG,MAAQ,GAAI,GAAI,GAAI,gBAAiB,CAAC,EAC9G,KAAK,EAAG,MAAQ,EAAG,EAAG,MAAQ,EAAG,MAAM,EAAI,KAAK,EAAI,EAAG,MAAQ,EAAG,GAAI,EAAG,MAAM,CACnF,CAEA,SAAS,gBAAgB,EAAG,MAAO,IAAK,CACtC,OAAO,KAAK,EAAI,EAAG,MAAQ,IAAM,EAAG,EAAG,IAAK,gBAAiB,CAAC,EAAI,KAAK,EAAI,IAAK,MAAQ,EAAG,EAAG,EAAG,MAAM,CACzG,CAGA,SAAS,WAAW,KAAM,CAAE,OAAO,MAAQ,MAAQ,MAAQ,IAAM,GAAK,MAAQ,IAAM,GAAK,EAAI,CAE7F,SAAS,UAAU,EAAG,EAAG,CAEvB,OAAO,KAAK,EAAG,EAAG,GAAI,GAAI,gBAAiB,CAAC,EAC1C,KAAK,EAAI,EAAG,EAAG,EAAI,EAAG,EAAI,EAAG,MAAM,EAAI,KAAK,EAAI,GAAI,EAAG,EAAI,GAAI,EAAI,EAAG,MAAM,EAC5E,OAAO,EAAI,EAAG,EAAI,EAAG,IAAK,SAAS,EAAI,OAAO,EAAI,GAAI,EAAI,EAAG,IAAK,SAAS,EAC3E,KAAK,EAAI,GAAI,EAAI,GAAI,EAAE,QAAQ,EAAG,gBAAiB,QAAQ,CAC/D,CAEA,SAAS,WAAW,EAAG,EAAG,MAAO,CAE/B,OAAO,KAAK,EAAG,EAAG,GAAI,GAAI,gBAAiB,CAAC,EAC1C,OAAO,EAAI,EAAG,EAAI,GAAI,IAAK,SAAS,EAAI,OAAO,EAAI,GAAI,EAAI,GAAI,IAAK,SAAS,EAC7E,KAAK,EAAI,GAAI,EAAI,GAAI,MAAO,gBAAiB,QAAQ,CACzD,CAEA,SAAS,UAAU,EAAG,QAAS,CAC7B,OAAO,KAAK,EAAG,QAAS,EAAG,QAAU,GAAI,MAAM,EAC7C,KAAK,EAAI,EAAG,QAAU,GAAI,EAAI,EAAG,QAAU,EAAE,EAAI,KAAK,EAAI,EAAG,QAAU,GAAI,EAAI,EAAG,QAAU,EAAE,EAAI,KAAK,EAAI,EAAG,QAAU,GAAI,EAAI,EAAG,QAAU,EAAE,CACnJ,CAEA,SAAS,YAAY,EAAG,EAAG,CAAE,OAAO,KAAK,EAAI,EAAG,EAAI,GAAI,GAAI,GAAI,gBAAiB,CAAC,EAAI,KAAK,EAAI,EAAG,EAAI,EAAG,EAAI,EAAG,EAAI,EAAG,MAAM,CAAG,CAEhI,SAAS,aAAa,EAAG,EAAG,CAE1B,OAAO,KAAK,EAAG,EAAG,GAAI,GAAI,gBAAiB,CAAC,EAAI,KAAK,EAAI,EAAG,EAAI,EAAG,EAAI,GAAI,EAAI,EAAG,eAAe,EAC/F,YAAY,EAAI,EAAG,EAAI,EAAE,CAC7B,CACA,SAAS,YAAY,EAAG,EAAG,CAAE,OAAO,KAAK,EAAG,EAAG,GAAI,GAAI,OAAQ,CAAC,EAAI,OAAO,EAAI,EAAG,EAAI,EAAG,IAAK,SAAS,CAAG,CAK1G,SAAS,YAAY,MAAO,IAAK,OAAQ,YAAa,CACpD,IAAI,EAAI,CAAC,EACL,EAAI,CAAC,EAET,EAAE,KAAK,KAAK,EAAG,EAAG,EAAG,IAAK,UAAU,CAAC,EACrC,EAAE,KAAK,+DAA+D,EAGtE,IAAI,GAAK,KAAK,IAAI,KAAK,IAAI,IAAM,MAAM,QAAU,EAAG,GAAG,EAAG,GAAG,EAC7D,EAAE,KAAK,iCAAmC,SAAS,MAAM,YAAa,IAAK,IAAK,GAAI,GAAI,EACtF,KAAK,IAAK,GAAI,IAAK,GAAI,QAAQ,EAAI,MAAM,EAC3C,EAAE,KAAK,KAAK,IAAK,GAAI,IAAK,IAAK,MAAM,CAAC,EACtC,EAAE,KAAK,KAAK,IAAK,GAAI,IAAK,IAAK,eAAe,CAAC,EAC/C,EAAE,KAAK,KAAK,IAAK,GAAI,IAAK,IAAK,eAAe,CAAC,EAC/C,EAAE,KAAK,KAAK,IAAK,GAAI,IAAK,IAAK,MAAM,CAAC,EAEtC,EAAE,KAAK,KAAK,IAAK,IAAK,IAAK,GAAI,eAAe,CAAC,EAE/C,EAAE,KAAK,KAAK,EAAG,IAAK,EAAG,IAAK,OAAO,CAAC,EACpC,EAAE,KAAK,KAAK,EAAG,IAAK,EAAG,IAAK,MAAM,CAAC,EACnC,EAAE,KAAK,KAAK,IAAK,IAAK,IAAK,GAAG,EAAI,KAAK,IAAK,IAAK,IAAK,GAAG,EAAI,KAAK,IAAK,IAAK,IAAK,GAAG,CAAC,EAErF,IAAI,GAAK,IACL,IAAI,OAAO,EAAE,KAAK,gBAAkB,GAAK,mDAAmD,EAChG,IAAI,IAAM,WAAW,OAAO,WAAW,EAAG,KAAO,IAAI,MAAQ,IAAM,IAC/D,aAAe,KAAO,IAAK,IAAM,GAAI,EAAE,KAAK,WAAW,GAAI,IAAI,CAAC,GAC/D,EAAE,KAAK,gBAAgB,GAAI,KAAM,GAAG,CAAC,EAC1C,EAAE,QAAU,CAAC,GAAI,KAAO,IAAM,EAAG,EAAG,EAAE,MAAQ,CAAC,GAAK,GAAI,GAAG,EAAG,EAAE,QAAU,CAAC,GAAK,EAAG,IAAK,GAAI,CAAC,EAE7F,IAAI,GAAK,IAAK,GAAK,IACnB,SAAE,KAAK,IAAI,IAAM,GAAK,SAAW,GAAK,UAAY,GAAK,SAAW,GAAK,GAAK,yDAA2D,GAAK,IAAM,UAAY,GAAK,OAAQ,EAAK,CAAC,EACjL,EAAE,MAAQ,CAAC,IAAK,GAAG,EACnB,EAAE,KAAK,WAAW,GAAI,GAAI,EAAE,SAAS,CAAC,CAAC,EACvC,EAAE,QAAU,CAAC,GAAK,GAAI,EAAE,EACxB,EAAE,KAAK,KAAK,KAAO,GAAK,IAAM,iBAAkB,QAAQ,CAAC,EACzD,EAAE,KAAK,UAAU,IAAK,GAAG,CAAC,EACnB,CAAE,IAAK,EAAE,KAAK,EAAE,EAAG,QAAS,CAAE,CACvC,CAGA,SAAS,WAAW,MAAO,IAAK,OAAQ,CACtC,IAAI,EAAI,CAAC,EACL,EAAI,CAAC,EACL,EAAI,IAAK,KAAO,IAAK,KAAO,IAC5B,OAAS,KAAO,GAAK,MAAQ,IACjC,SAAS,MAAM,EAAG,CAAE,OAAO,KAAO,KAAK,IAAI,EAAI,GAAG,EAAI,KAAO,CAC7D,IAAI,IAAM,MAAM,SACZ,QAAU,MAAQ,SAAW,MAAM,mBAAqB,UACxD,YAAc,CAAC,SAAW,MAAQ,SAAW,MAAM,QAAU,SAC7D,YAAc,CAAC,EAAE,QAAU,OAAO,aAClC,EAAI,MAAM,QAEd,EAAE,KAAK,SAAS,MAAM,YAAa,IAAK,IAAK,EAAG,CAAC,CAAC,EAClD,EAAE,KAAK,SAAS,MAAM,YAAa,EAAG,IAAK,EAAG,EAAG,CAAC,EAElD,EAAE,KAAK,KAAK,EAAG,EAAG,EAAG,EAAG,MAAM,CAAC,EAC/B,QAAS,GAAK,EAAG,GAAK,EAAG,IAAM,GAAI,EAAE,KAAK,KAAK,GAAI,EAAI,EAAG,GAAK,EAAG,EAAI,GAAI,eAAe,CAAC,EAE1F,EAAE,KAAK,KAAK,IAAK,KAAM,GAAI,EAAI,KAAM,YAAY,CAAC,EAClD,EAAE,KAAK,KAAK,IAAK,KAAM,GAAI,EAAI,KAAM,YAAY,CAAC,EAC9C,cACF,EAAE,KAAK,8DAA8D,EACrE,EAAE,KAAK,KAAK,IAAK,IAAK,IAAK,IAAK,eAAe,EAAI,KAAK,IAAK,IAAK,IAAK,GAAG,EAAI,KAAK,IAAK,IAAK,IAAK,GAAG,CAAC,GAExG,EAAE,KAAK,KAAK,IAAK,KAAM,IAAK,KAAM,MAAM,CAAC,EACzC,EAAE,KAAK,KAAK,SAAW,KAAO,IAAM,SAAW,KAAO,UAAY,KAAO,IAAK,cAAc,CAAC,EAE7F,EAAE,KAAK,KAAK,IAAK,IAAK,IAAK,GAAG,EAAI,KAAK,IAAK,IAAK,IAAK,CAAC,EAAI,KAAK,IAAK,IAAK,IAAK,CAAC,CAAC,EAEjF,IAAI,KAAM,QAAS,OAAS,WAAW,QAAU,OAAO,IAAI,EAC5D,GAAI,MAAQ,OAAQ,CAClB,IAAI,KAAO,KAAK,IAAI,KAAK,IAAI,GAAK,EAAI,IAAK,EAAE,EAAG,KAAO,OAAS,EAAE,EAClE,KAAO,IAAK,QAAU,KAAO,KAC7B,EAAE,KAAK,KAAK,IAAK,QAAS,EAAG,KAAO,EAAG,eAAe,CAAC,EACvD,EAAE,KAAK,KAAK,SAAW,KAAO,GAAK,UAAY,KAAO,GAAK,UAAY,KAAO,GAAK,gBAAkB,KAAO,GAAK,SAAU,MAAM,CAAC,EAClI,EAAE,MAAQ,CAAC,IAAK,KAAO,EAAG,GAAI,CAAC,CACjC,SAAW,MAAQ,QACjB,KAAO,IAAK,QAAU,KAAO,EAAG,OAAS,QAAU,GAAK,GAAK,QAAU,GAAK,GAAK,GACjF,EAAE,KAAK,KAAK,KAAO,KAAO,IAAM,IAAM,EAAE,MAAM,KAAO,EAAE,EAAI,CAAC,EAAI,MAAQ,KAAO,IAAM,KAAO,QAAU,IAAM,MAAQ,KAAO,GAAK,KAAO,QAAU,IAAK,MAAM,CAAC,EAC7J,EAAE,MAAQ,CAAC,KAAO,GAAI,QAAU,EAAE,MAC7B,CAEL,KAAO,IACP,IAAI,SAAW,KAAK,IAAI,KAAK,IAAI,EAAI,GAAK,EAAI,GAAI,GAAG,EAAG,GAAG,EAC3D,QAAU,SAAW,GACrB,EAAE,KAAK,KAAK,QAAU,SAAW,MAAQ,KAAO,GAAK,IAAM,SAAW,UAAY,SAAW,IAAM,UAAY,SAAW,IAAK,MAAM,CAAC,EACtI,EAAE,MAAQ,CAAC,IAAK,QAAQ,CAC1B,CACA,EAAE,KAAK,YAAc,aAAa,KAAM,QAAS,EAAI,EAAI,gBAAgB,KAAM,QAAS,MAAM,CAAC,EAC/F,EAAE,QAAU,CAAC,KAAM,QAAU,OAAS,EAAG,EAEzC,IAAI,KAAM,KAAM,IAChB,GAAI,QAAS,CAEX,IAAI,GAAI,GAAI,IACR,KACJ,GAAI,MAAQ,OAEV,KAAO,KAAM,KAAO,QAAU,GAAI,GAAK,IAAK,GAAK,QAAU,EAAG,KAAO,GAAK,GAC1E,IAAM,SAAW,GAAK,IAAM,SAAW,EAAE,MAAM,GAAG,EAAI,CAAC,EAAI,SAAW,EAAE,MAAM,GAAG,EAAI,CAAC,EAAI,kCACrF,CACL,KAAO,KAAM,KAAO,QAAU,GAAI,GAAK,IAAK,GAAK,QAAU,EAC3D,IAAI,GAAK,KAAK,IAAI,GAAK,GAAI,GAAG,EAC9B,IAAM,SAAW,GAAK,IAAM,SAAW,GAAK,SAAW,GAAK,YAC5D,KAAO,EACT,CACA,EAAE,KAAK,aAAa,GAAI,EAAE,CAAC,EAC3B,EAAE,KAAK,IAAI,IAAM,KAAO,IAAM,QAAU,KAAO,KAAO,KAAO,KAAO,IAAM,KAAO,KAAO,KAAO,KAAO,IAAM,KAAO,KAAO,KAAO,KAAO,IAAM,KAAO,KAAO,KAAO,KAAO,IAAK,EAAK,CAAC,EACjL,IAAI,UAAU,EAAE,KAAK,YAAY,KAAM,IAAI,CAAC,EAChD,EAAE,KAAK,KAAK,IAAK,QAAQ,CAAC,EAC1B,EAAE,KAAK,KAAK,IAAK,IAAK,GAAI,GAAI,gBAAiB,CAAC,CAAC,EACjD,EAAE,KAAK,KAAK,sCAAuC,QAAQ,CAAC,EAC5D,EAAE,KAAK,UAAU,IAAK,GAAG,CAAC,EAC1B,IAAI,KAAO,MAAQ,OACnB,EAAE,UAAY,KAAO,CAAC,GAAI,GAAK,GAAI,IAAK,EAAE,EAAI,CAAC,GAAK,GAAI,GAAK,GAAI,GAAI,EAAE,EACvE,EAAE,QAAU,KAAO,CAAC,GAAK,GAAI,GAAK,GAAI,IAAK,GAAG,EAAI,CAAC,GAAK,GAAI,GAAK,GAAI,GAAI,GAAG,EAC5E,EAAE,SAAW,KAAO,CAAC,KAAO,EAAG,KAAM,GAAI,EAAE,EAAI,CAAC,KAAO,EAAG,KAAM,IAAK,EAAE,EACvE,EAAE,QAAU,KAAO,CAAC,KAAO,EAAG,KAAO,EAAG,GAAI,EAAE,EAAI,CAAC,KAAO,EAAG,KAAO,EAAG,IAAK,EAAE,EAC9E,EAAE,MAAQ,IACZ,KAAO,CACL,IAAI,GAAK,IAAK,GAAK,IAAK,MAAQ,IAChC,EAAE,KAAK,WAAW,GAAI,GAAI,EAAE,SAAS,CAAC,CAAC,EACvC,EAAE,QAAU,CAAC,GAAK,GAAI,EAAE,EACxB,IAAI,MAAO,KAAO,KAClB,GAAI,MAAQ,QACV,KAAO,IAAK,KAAO,IACnB,MAAQ,IAAM,KAAO,IAAM,QAAU,KAAO,KAAO,KAAO,KAAO,GAAK,KAAO,KAAO,KAAO,KAAO,IAAM,KAAO,KAAO,GAAK,KAAO,KAAO,IAAM,MAAQ,KAAO,GAAK,KAAO,KAAO,IAAM,KAAO,KAAO,KAAO,KAAO,IAAM,IAAM,KAAO,KAAO,KAAO,IAAM,KAAO,KAAO,KAAO,KAAO,IACpR,KAAO,KAAO,KAAO,KAAO,IAAM,KAAO,KAAO,KAAO,MAAQ,GAAK,KAAO,KAAO,IAAM,MAAQ,KAAO,KAAO,GAAK,IAAM,MAAQ,MAAQ,GAAK,IAAM,IAAM,MAC5J,EAAE,MAAQ,CAAC,KAAO,GAAI,KAAO,EAAE,EAC/B,EAAE,WAAa,CAAC,KAAM,KAAO,EAAE,EAC/B,IAAM,KAAO,KAAO,GAAK,IAAM,KAAO,SAAW,KAAO,SAAW,EACnE,EAAE,KAAK,UAAU,IAAK,CAAC,CAAC,MACnB,CACL,IAAI,MAAQ,MAAQ,OAAS,IAAM,KACnC,KAAO,MAAO,KAAO,MAAQ,OAAS,IAAM,KAAK,IAAI,QAAU,GAAI,GAAG,EACtE,IAAI,IAAM,MAAQ,OACd,IAAM,KAAO,IAAM,QAAU,KAAO,KAAO,KAAO,QAAU,GAAK,UAAY,QAAU,GAAK,UAAY,KAAO,GAAK,SAAW,EAAE,MAAM,GAAG,EAAI,CAAC,EAAI,UAAY,KAAO,IACtK,IAAM,KAAO,IAAM,QAAU,KAAO,KAAO,KAAO,KAAO,IACzD,OAAS,YAAc,IAAM,MAC7B,MAAQ,KAAO,MAAQ,KAAO,KAAO,IAAM,KAAO,MAAQ,KAAO,OAAS,GAAK,KAAO,MAAQ,IAAM,OAAS,KAAO,MAAQ,GAAK,IAAM,OAAS,MAAQ,GAAK,IAAM,IAAM,OACzK,aAAe,MAAQ,IAAK,KAAO,OAClC,MAAQ,IAAM,MACnB,EAAE,MAAQ,MAAQ,OAAS,CAAC,IAAK,EAAE,MAAM,GAAG,EAAI,CAAC,CAAC,EAAI,CAAC,MAAO,QAAU,MAAQ,CAAC,EACjF,EAAE,WAAa,CAAC,IAAK,MAAM,EAC3B,IAAM,KAAO,MAAQ,GAAK,IAAM,KAAO,MAAQ,MAAQ,IAAM,IAAM,KAAO,MAAQ,MAAQ,IAAM,IAAM,EACtG,EAAE,KAAK,UAAU,MAAQ,GAAI,CAAC,CAAC,EAC1B,aAAa,EAAE,KAAK,OAAO,IAAK,MAAO,EAAG,MAAM,CAAC,CACxD,CACA,EAAE,KAAK,IAAI,MAAO,EAAK,CAAC,EACpB,MAAM,EAAE,KAAK,IAAI,KAAM,EAAI,CAAC,EAC5B,IAAI,WAAY,EAAE,KAAK,YAAY,KAAM,IAAI,CAAC,EAAG,EAAE,KAAK,KAAK,IAAK,QAAQ,CAAC,GAC/E,EAAE,SAAW,CAAC,KAAM,IAAI,EACxB,EAAE,QAAU,CAAC,KAAM,KAAO,CAAC,EAC3B,EAAE,KAAK,KAAK,IAAM,GAAK,kCAAmC,QAAQ,CAAC,EACnE,EAAE,KAAK,UAAU,IAAK,GAAG,CAAC,CAC5B,CACA,GAAI,SAAW,IAAI,SAAU,CAE3B,IAAI,MAAQ,MAAQ,OAChB,KAAO,KAAO,GAAK,IAAM,KAAO,SAAW,KAAO,UAAY,KAAO,GAAK,UAAY,KAAO,GAAK,SAAW,EAC7G,KAAO,KAAO,GAAK,IAAM,KAAO,SAAW,KAAO,SAAW,EACjE,EAAE,KAAK,KAAK,MAAO,QAAQ,CAAC,EAC5B,EAAE,KAAK,UAAU,MAAQ,OAAS,IAAM,IAAK,CAAC,CAAC,CACjD,CAGA,IAAI,KAAO,MAAQ,OAAS,IAAM,IAC9B,OAAS,QACb,SAAE,KAAK,KAAK,KAAM,EAAG,KAAM,OAAQ,QAAQ,EAAI,KAAK,KAAO,EAAG,OAAQ,KAAO,EAAG,OAAQ,MAAM,EAAI,KAAK,KAAO,EAAG,EAAG,KAAO,EAAG,EAAG,MAAM,CAAC,EACxI,EAAE,KAAK,KAAK,IAAM,KAAO,IAAM,OAAS,oBAAsB,KAAO,IAAM,EAAI,mBAAoB,SAAS,CAAC,EAC7G,EAAE,KAAK,KAAK,KAAO,GAAI,OAAQ,KAAO,EAAG,OAAQ,QAAQ,CAAC,EACnD,CAAE,IAAK,EAAE,KAAK,EAAE,EAAG,QAAS,CAAE,CACvC,CAIA,IAAI,YAAc,CAChB,YAAa,UAAW,YAAa,UAAW,aAAc,UAAW,oBAAqB,UAC9F,YAAa,QAAS,SAAU,QAAS,YAAa,aAAc,eAAgB,aACpF,SAAU,WAAY,YAAa,WAAY,cAAe,UAC9D,aAAc,QAAS,WAAY,QAAS,WAAY,QACxD,aAAc,YAAa,kBAAmB,YAAa,iBAAkB,YAC7E,WAAY,UAAW,cAAe,SACxC,EAEI,OAAS,CACX,QAAS,CAAC,GAAI,GAAG,EAAG,MAAO,CAAC,IAAK,EAAE,EAAG,WAAY,CAAC,GAAI,EAAE,EAAG,SAAU,CAAC,GAAI,GAAG,EAAG,QAAS,CAAC,GAAI,EAAE,EACjG,MAAO,CAAC,IAAK,GAAG,EAAG,UAAW,CAAC,GAAI,EAAE,EAAG,QAAS,CAAC,IAAK,GAAG,CAC5D,EAEA,SAAS,UAAU,KAAM,CAAE,OAAO,YAAY,IAAI,GAAK,IAAM,CAE7D,SAAS,SAAS,MAAO,QAAS,GAAI,CACpC,IAAI,GAAK,GAAG,CAAC,EAAG,GAAK,GAAG,CAAC,EAAG,GAAK,GAAG,CAAC,EAAI,GAAG,CAAC,EAAG,GAAK,GAAG,CAAC,EAAI,GAAG,CAAC,EAC7D,IAAM,CAAC,EACP,KAAO,CAAC,EACR,OAAS,CAAC,EACd,aAAM,QAAQ,SAAU,GAAI,EAAG,CAC7B,IAAI,IAAM,UAAU,GAAG,IAAI,EACvB,GAAK,KAAO,QAAQ,GAAG,EAC3B,GAAK,GAML,SALI,IAAM,GAAG,OAAS,EAAI,CAAC,GAAG,CAAC,EAAG,GAAG,CAAC,CAAC,EAAK,OAAO,GAAG,GAAK,CAAC,GAAI,GAAG,EAC/D,EAAK,KAAK,GAAG,GAAK,KAAK,GAAG,GAAK,GAAK,EACpC,GAAK,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC,EAAI,IAAI,CAAC,GAAK,EAAI,GAAK,GAAI,GAAK,EAAE,EAAG,GAAK,EAAE,EACvE,GAAK,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC,EAAI,IAAI,CAAC,EAAG,GAAK,EAAE,EAAG,GAAK,EAAE,EAEnD,MAAQ,EAAG,MAAQ,GAAK,OAAO,KAAK,SAAU,EAAG,CAAE,OAAO,KAAK,IAAI,EAAE,CAAC,EAAI,EAAE,EAAI,IAAM,KAAK,IAAI,EAAE,CAAC,EAAI,EAAE,EAAI,EAAI,CAAC,EAAG,QAC3H,IAAM,GAAK,GAAK,GAAK,IAAM,GAE7B,OAAO,KAAK,CAAC,GAAI,EAAE,CAAC,EACpB,IAAI,KAAK,kCAAoC,EAAI,GAAK,gBAAkB,EAAI,KAAO,KAAK,GAAG,CAAC,EAAG,GAAG,CAAC,EAAG,GAAI,GAAI,SAAS,EACrH,OAAO,GAAG,CAAC,EAAG,GAAG,CAAC,EAAG,IAAK,gBAAgB,EAAI,OAAO,GAAI,GAAI,GAAI,QAAQ,EACzE,YAAc,EAAE,EAAE,EAAI,QAAU,EAAE,GAAK,CAAC,EAAI,4CAA8C,EAAI,GAAK,aAAa,EACpH,CAAC,EACM,IAAI,KAAK,EAAE,CACpB,CAEA,IAAI,UAAY,CAAE,OAAQ,sBAAuB,MAAO,QAAS,KAAM,eAAgB,KAAM,aAAc,EACvG,UAAY,CAAE,KAAM,aAAc,SAAU,iBAAkB,MAAO,mBAAoB,MAAO,iBAAkB,EAEtH,SAAS,SAAS,MAAO,OAAQ,CAC/B,OAAO,EAAE,8FAA+F,CACtG,SAAU,EAAE,UAAU,MAAM,QAAQ,GAAK,EAAE,EAAE,YAAY,EACzD,YAAa,EAAE,UAAU,MAAM,WAAW,GAAK,EAAE,EAAE,YAAY,EAC/D,OAAQ,OAAO,OAAS,CAAC,GAAG,KAAK,EAAE,SAAS,CAAC,CAC/C,CAAC,CACH,CAMA,SAAS,KAAK,MAAO,OAAQ,CAC3B,OAAS,QAAU,CAAE,MAAO,CAAC,EAAG,MAAO,CAAC,CAAE,EAC1C,IAAI,IAAM,CAAC,GACV,OAAO,OAAS,CAAC,GAAG,QAAQ,SAAU,GAAI,CAAE,IAAI,EAAI,UAAU,GAAG,IAAI,EAAO,IAAG,IAAI,CAAC,EAAI,GAAM,CAAC,EAChG,IAAI,aAAe,OAAO,OAAS,CAAC,GAAG,KAAK,SAAU,GAAI,CAAE,OAAO,GAAG,OAAS,qBAAuB,CAAC,EACnG,MAAQ,MAAM,WAAa,SAC3B,YAAY,MAAO,IAAK,OAAQ,WAAW,EAC3C,WAAW,MAAO,IAAK,CAAE,YAA0B,KAAM,OAAO,WAAY,CAAC,EAC7E,KAAO,SAAS,MAAO,MAAM,EAE7B,GAAK,MAAM,WAAa,QAAU,MAAM,WAAa,QAAU,CAAC,GAAI,GAAI,IAAK,GAAG,EAAI,CAAC,EAAG,EAAG,EAAG,CAAC,EACnG,MAAO,sCAAwC,GAAG,KAAK,GAAG,EAAI,oGAClC,IAAI,IAAI,EAAI,0jBAOpB,EAAI,aAAe,EAAI,iCACvB,EAAI,aAAe,EAAI,0CACvB,EAAI,aAAe,EAAI,kDAChB,MAAM,IAAM,OACrC,SAAS,OAAO,OAAS,CAAC,EAAG,MAAM,QAAS,EAAE,EAC9C,QACJ,CAEA,IAAI,IAAM,CAAE,KAAY,UAAsB,WAAyB,EACnE,OAAO,OAAW,KAAe,OAAO,QAAS,OAAO,QAAU,IACjE,OAAO,YAAc,GAC5B,GAAG,OAAO,OAAW,IAAc,OAAS,UAAU,GAerD,SAAU,OAAQ,CACjB,aAEA,IAAI,EAAI,OAAO,OAAW,KAAe,OAAO,QAAU,QAAQ,WAAW,EAAI,OAAO,SACpF,EAAI,EAAE,EAAG,IAAM,EAAE,IAIjB,cAAgB,CAAE,OAAQ,KAAO,OAAQ,KAAO,OAAQ,IAAM,EAE9D,YAAc,GACd,SAAW,IAEX,cAAgB,GAEhB,aAAe,EAEf,cAAgB,EAEhB,gBAAkB,IAEtB,SAAS,OAAO,EAAG,CAAE,OAAO,KAAK,MAAM,EAAI,EAAE,EAAI,EAAI,CACrD,SAAS,OAAO,EAAG,CAAE,OAAO,KAAK,MAAM,EAAI,GAAG,EAAI,GAAK,CAOvD,SAAS,eAAe,QAAS,cAAe,CAC9C,IAAI,GAAK,eAAwB,gBACjC,OAAO,OAAO,MAAQ,KAAK,KAAK,KAAK,IAAI,QAAS,CAAC,CAAC,EAAI,KAAK,KAAK,EAAE,EAAE,CACxE,CAGA,SAAS,mBAAmB,MAAO,CACjC,GAAI,MAAM,WAAa,UAAY,MAAM,YACvC,MAAO,CAAE,KAAM,sBAAuB,IAAK,EAAE,8MAA8M,CAAE,EAE/P,GAAI,MAAM,YACR,MAAO,CAAE,KAAM,sBAAuB,IAAK,EAAE,oKAAoK,CAAE,EAErN,GAAI,MAAM,WAAa,SACrB,MAAO,CAAE,KAAM,cAAe,IAAK,EAAE,yIAAyI,CAAE,EAElL,IAAI,EAAI,MAAM,QACd,OAAQ,MAAM,YAAa,CACzB,IAAK,OACH,OAAO,GAAK,GACR,CAAE,KAAM,cAAe,IAAK,EAAE,kIAAkI,CAAE,EAClK,CAAE,KAAM,cAAe,IAAK,EAAE,yJAA0J,CAAE,EAChM,IAAK,QACH,OAAO,GAAK,GACR,CAAE,KAAM,cAAe,IAAK,EAAE,4LAA6L,CAAE,EAC7N,CAAE,KAAM,cAAe,IAAK,EAAE,qGAAqG,CAAE,EAC3I,IAAK,QACH,OAAO,GAAK,EACR,CAAE,KAAM,eAAgB,IAAK,EAAE,wHAAwH,CAAE,EACzJ,CAAE,KAAM,cAAe,IAAK,EAAE,kGAAkG,CAAE,EACxI,QACE,MAAO,CAAE,KAAM,cAAe,IAAK,EAAE,yHAAyH,CAAE,CACpK,CACF,CAGA,SAAS,aAAa,MAAO,CAC3B,GAAI,CAAC,MAAO,OAAO,KACnB,IAAI,EAAI,qDAAqD,KAAK,KAAK,EACvE,GAAI,EAAG,OAAO,WAAW,EAAE,CAAC,CAAC,EAC7B,IAAI,EAAI,sCAAsC,KAAK,KAAK,EACxD,OAAI,EAAU,OAAO,WAAW,EAAE,CAAC,CAAC,EAAI,KAAM,EACvC,IACT,CAGA,SAAS,qBAAqB,SAAU,KAAM,CAC5C,IAAI,KAAO,SAAS,OAAO,SAAU,EAAG,CAAE,OAAO,EAAE,SAAW,CAAC,EAC/D,GAAI,CAAC,KAAK,OAAQ,MAAO,CAAE,QAAS,KAAM,QAAS,IAAK,EACxD,IAAI,QAAU,KACX,IAAI,SAAU,EAAG,CAAE,MAAO,CAAE,EAAM,IAAK,aAAa,EAAE,KAAK,CAAE,CAAG,CAAC,EACjE,OAAO,SAAU,EAAG,CAAE,OAAO,EAAE,MAAQ,IAAM,CAAC,EAC9C,KAAK,SAAU,EAAG,EAAG,CAAE,OAAO,EAAE,IAAM,EAAE,GAAK,CAAC,EACjD,GAAI,CAAC,QAAQ,OAAQ,MAAO,CAAE,QAAS,KAAK,CAAC,EAAG,QAAS,IAAK,EAC9D,QAAS,EAAI,EAAG,EAAI,QAAQ,OAAQ,IAClC,GAAI,QAAQ,CAAC,EAAE,KAAO,KAAM,MAAO,CAAE,QAAS,QAAQ,CAAC,EAAE,EAAG,QAAS,QAAQ,CAAC,EAAE,GAAI,EAEtF,IAAI,QAAU,QAAQ,QAAQ,OAAS,CAAC,EACxC,MAAO,CAAE,QAAS,QAAQ,EAAG,QAAS,QAAQ,IAAK,MAAO,EAAK,CACjE,CAEA,IAAI,UAAY,CACd,YAAa,mBAAoB,YAAa,mBAAoB,aAAc,oBAAqB,oBAAqB,sBAC1H,YAAa,0CAA2C,SAAU,qCAAsC,YAAa,oBAAqB,eAAgB,2BAC1J,SAAU,qBAAsB,YAAa,qBAAsB,cAAe,2BAA4B,aAAc,wBAC5H,WAAY,eAAgB,WAAY,YAAa,aAAc,gCACnE,iBAAkB,2BAA4B,kBAAmB,4BACjE,WAAY,sBAAuB,cAAe,eACpD,EAII,YAAc,CAChB,WAAY,kNACZ,cAAe,2UACjB,EAGA,SAAS,YAAY,QAAS,KAAM,CAClC,IAAI,MAAQ,QAAQ,IAAI,GAAK,CAAC,GAAG,OAAO,OAAO,EAC/C,GAAI,CAAC,KAAK,OAAQ,OAAO,KACzB,QAAS,EAAI,EAAG,EAAI,KAAK,OAAQ,IAAK,GAAI,KAAK,CAAC,EAAE,WAAa,sBAAsB,KAAK,CAAC,CAAC,EAAG,OAAO,KAAK,CAAC,EAC5G,OAAO,IACT,CAEA,SAAS,sBAAsB,EAAG,CAChC,OAAQ,EAAE,UAAY,CAAC,GAAG,KAAK,SAAU,EAAG,CAAE,OAAO,EAAE,SAAW,CAAC,GAAK,IAC1E,CASA,SAAS,UAAU,MAAO,QAAS,CAEjC,IAAI,MAAQ,MAAM,YAAc,KAAO,MAAM,aACzC,OAAS,MAAM,WAAa,SAG5B,QAAU,MAAM,aAAe,EAAE,YAAY,QAAS,eAAe,GAAK,YAAY,QAAS,aAAa,KAC9G,MAAQ,OAAO,OAAO,CAAC,EAAG,MAAO,CAAE,YAAa,EAAM,CAAC,GAGzD,IAAI,eAAiB,CAAC,QAAU,MAAM,WAAa,SAAW,MAAM,mBAAqB,UACrF,UAAY,CAAC,QAAU,CAAC,gBAAkB,MAAM,QAAU,SAC1D,MAAQ,CAAC,EACT,OAAS,CAAC,EACV,MAAQ,CAAC,EACT,MAAQ,CAAC,EACT,gBAAkB,KAEtB,SAAS,IAAI,KAAM,OAAQ,QAAS,CAClC,IAAI,EAAI,YAAY,QAAS,IAAI,EACjC,GAAI,CAAC,EAAG,OAAO,KACf,IAAI,KAAO,CAAE,KAAY,QAAS,EAAG,QAAS,SAAW,sBAAsB,CAAC,EAAG,OAAgB,SAAU,CAAE,EAC/G,aAAM,KAAK,IAAI,EACR,IACT,CACA,SAAS,KAAK,MAAO,GAAI,CAAE,OAAO,KAAK,CAAE,MAAc,GAAI,OAAO,EAAE,CAAE,CAAC,CAAG,CAG1E,IAAI,IAAM,mBAAmB,KAAK,EAC9B,IAAM,IAAI,IAAI,KAAM,IAAI,GAAG,EAC/B,GAAI,CAAC,IAEH,QADI,SAAW,CAAC,cAAe,cAAe,cAAc,EACnD,GAAK,EAAG,GAAK,SAAS,QAAU,CAAC,IAAK,KACzC,SAAS,EAAE,IAAM,IAAI,OAAQ,IAAM,CAAE,KAAM,SAAS,EAAE,EAAG,IAAK,IAAI,GAAI,EAAG,IAAM,IAAI,SAAS,EAAE,EAAG,IAAI,GAAG,GAGhH,IAAI,KAAO,KAAO,IAAI,QAAQ,MAAQ,KAAO,OAAO,IAAI,QAAQ,IAAI,EAAI,KACpE,YAAc,IAAI,OAAS,sBAG/B,GAFA,MAAM,KAAK,EAAE,IAAO,YAAc,iCAAmC,mBAAsB,SAAS,CAAC,EAEjG,QAAU,YAAa,CACzB,IAAI,GAAK,YAAY,QAAS,aAAa,EACvC,GAAK,qBAAqB,GAAG,SAAU,YAAY,EACvD,IAAI,gBAAiB,EAAE,iGAAiG,CAAC,EACzH,IAAI,cAAe,EAAE,sIAAsI,EAAG,GAAG,OAAO,EACxK,MAAM,KAAK,EAAE,uBAAuB,CAAC,EACrC,MAAM,KAAK,WAAa,OAAO,GAAG,OAAO,CAAC,EACtC,GAAG,SAAW,MAAM,KAAK,OAAO,GAAG,OAAO,EAAI,WAAY,GAAG,QAAU,cAAc,MAAM,EAC/F,KAAK,EAAE,SAAS,EAAG,aAAa,EAChC,KAAK,EAAE,kBAAmB,CAAE,EAAG,CAAE,CAAC,EAAG,EAAI,aAAa,CACxD,SAAW,OAAQ,CACjB,IAAI,KAAO,IAAI,eAAgB,EAAE,yJAAyJ,CAAC,EAC3L,GAAI,KACF,MAAM,KAAK,EAAE,4BAA4B,CAAC,EAC1C,KAAK,EAAE,0BAA0B,EAAG,aAAe,cAAc,MAAM,EACvE,KAAK,EAAE,kBAAmB,CAAE,EAAG,CAAE,CAAC,EAAG,EAAI,aAAa,EACtD,MAAM,KAAK,EAAE,oFAAoF,CAAC,MAC7F,CAEL,IAAI,GAAK,YAAY,QAAS,aAAa,EAC3C,GAAI,GAAI,CACN,IAAI,GAAK,qBAAqB,GAAG,SAAU,YAAY,EACvD,IAAI,cAAe,EAAE,kKAAkK,EAAG,GAAG,OAAO,EACpM,MAAM,KAAK,WAAa,OAAO,GAAG,OAAO,CAAC,EACtC,GAAG,SAAW,MAAM,KAAK,OAAO,GAAG,OAAO,EAAI,WAAY,GAAG,QAAU,cAAc,MAAM,EAC/F,KAAK,EAAE,kBAAmB,CAAE,EAAG,CAAE,CAAC,EAAG,EAAI,aAAa,CACxD,CACF,CACF,KAAO,CACL,IAAI,WAAa,IAAM,EAAE,oFAAqF,EAC1G,IAAM,YAAY,QAAS,UAAU,EACrC,MAAQ,IAAM,KAAO,YAAY,QAAS,aAAa,EAGvD,KAAO,OAAS,CAAC,aAAe,CAAC,eAAiB,YAAY,QAAS,gBAAgB,EAAI,KAC3F,YAAc,CAAC,CAAC,KACpB,GAAI,YAAa,CACf,IAAI,QAAU,KAAK,IAAI,MAAM,KAAO,cAAe,CAAC,EACpD,GAAI,QAAU,EAAG,CACf,IAAI,IAAM,YAAY,QAAS,UAAU,EACzC,GAAI,IAAK,CACP,IAAI,GAAK,qBAAqB,IAAI,SAAU,OAAO,EACnD,IAAI,WAAY,EAAE,wHAAwH,EAAG,GAAG,OAAO,EACvJ,MAAM,KAAK,WAAa,OAAO,GAAG,OAAO,CAAC,EACtC,GAAG,SAAW,MAAM,KAAK,OAAO,GAAG,OAAO,EAAI,WAAY,GAAG,QAAU,cAAc,MAAM,EAC3F,GAAG,OAAO,MAAM,KAAK,EAAE,2JAA4J,CAAE,IAAK,OAAO,GAAG,OAAO,CAAE,CAAC,CAAC,CACrN,CACF,CACA,IAAI,cAAe,EAAE,yHAAyH,EAAI,UAAU,EAC5J,MAAM,KAAK,EAAE,oCAAoC,CAAC,EAClD,KAAK,EAAE,4CAA4C,EAAG,QAAQ,EAC9D,IAAI,iBACA,EADkB,UAChB,gLACA,gLAD+K,CACE,EACvL,MAAM,KAAK,EAAE,0CAA0C,CAAC,EACxD,KAAK,EAAE,0BAA0B,EAAG,cAAgB,cAAc,MAAM,EACxE,KAAK,EAAE,kBAAmB,CAAE,EAAG,QAAU,EAAI,EAAI,CAAE,CAAC,GAAI,QAAU,EAAI,EAAI,GAAK,aAAa,CAC9F,SAAW,MAAO,CAGhB,IAAI,cAAe,EAAE,0GAA0G,EAAI,UAAU,EAC7I,IAAI,GAAK,IAAI,gBACT,EAD0B,YACxB,oIACA,4GADmI,CACtB,EAC/G,IAAM,cAAa,GAAG,SAAW,GACjC,cAAe,MAAM,KAAK,EAAE,uBAAuB,CAAC,EAAG,KAAK,EAAE,SAAS,EAAG,aAAa,GAC3F,MAAM,KAAK,EAAE,oCAAoC,CAAC,EAClD,KAAK,EAAE,4CAA4C,EAAG,QAAQ,EAC9D,MAAM,KAAK,EAAE,uBAAuB,CAAC,EACrC,KAAK,EAAE,SAAS,EAAG,aAAa,CAClC,KAAO,CACL,IAAI,IAAM,IAAI,WAAY,EAAE,uEAAuE,EAAI,UAAU,EAC7G,MACF,MAAM,KAAK,EAAE,oBAAoB,CAAC,EAClC,KAAK,EAAE,wCAAwC,EAAG,WAAW,GAE3D,cACF,IAAI,gBAAiB,EAAE,yHAAyH,CAAC,EACjJ,MAAM,KAAK,EAAE,uBAAuB,CAAC,EACrC,KAAK,EAAE,SAAS,EAAG,aAAa,EAEpC,CAEA,GAAI,aAEG,GAAI,eAAgB,CACzB,IAAI,QAAU,QAAU,KAAO,eAAiB,QAAU,SAAW,mBAAqB,oBACtF,IAAM,IAAI,QAAS,EAAE,4LAA4L,CAAC,EAClN,KAAK,MAAM,KAAK,EAAE,8BAA8B,CAAC,EACjD,QAAU,SAAS,MAAM,KAAK,EAAE,6IAA6I,CAAC,EAClL,KAAK,EAAE,kBAAmB,CAAE,EAAG,CAAE,CAAC,EAAG,EAAI,aAAa,EACtD,gBAAkB,EAAE,6EAA8E,CACpG,SAAW,UAAW,CACpB,IAAI,YAAc,KAAK,IAAI,MAAM,KAAO,cAAe,CAAC,EACxD,GAAI,YAAc,EAAG,CACnB,IAAI,IAAM,YAAY,QAAS,UAAU,EACzC,GAAI,IAAK,CACP,IAAI,KAAO,qBAAqB,IAAI,SAAU,WAAW,EACzD,IAAI,WAAY,EAAE,kGAAkG,EAAG,KAAK,OAAO,EACnI,MAAM,KAAK,WAAa,OAAO,KAAK,OAAO,CAAC,EACxC,KAAK,SAAW,MAAM,KAAK,OAAO,KAAK,OAAO,EAAI,WAAY,KAAK,QAAU,cAAc,MAAM,EACjG,KAAK,OAAO,MAAM,KAAK,EAAE,2JAA4J,CAAE,IAAK,OAAO,KAAK,OAAO,CAAE,CAAC,CAAC,CACzN,CACF,CACA,IAAI,cAAe,EAAE,6HAA8H,CAAC,EACpJ,MAAM,KAAK,EAAE,kBAAkB,CAAC,EAChC,KAAK,EAAE,0BAA0B,EAAG,cAAgB,cAAc,MAAM,EACxE,KAAK,EAAE,kBAAmB,CAAE,EAAG,YAAc,EAAI,EAAI,CAAE,CAAC,GAAI,YAAc,EAAI,EAAI,GAAK,aAAa,CACtG,KAAO,CACL,IAAI,EAAI,YAAY,QAAS,aAAa,EAC1C,GAAI,EAAG,CACL,IAAI,GAAK,qBAAqB,EAAE,SAAU,MAAM,IAAI,EACpD,IAAI,cAAe,EAAE,qFAAqF,EAAG,GAAG,OAAO,EACvH,MAAM,KAAK,WAAa,OAAO,GAAG,OAAO,CAAC,EACtC,GAAG,SAAW,MAAM,KAAK,OAAO,GAAG,OAAO,EAAI,WAAY,GAAG,QAAU,cAAc,MAAM,EAC/F,KAAK,EAAE,kBAAmB,CAAE,EAAG,CAAE,CAAC,EAAG,EAAI,aAAa,EAClD,GAAG,OAAO,MAAM,KAAK,EAAE,2JAA4J,CAAE,IAAK,OAAO,GAAG,OAAO,EAAG,IAAK,IAAI,MAAM,IAAI,CAAE,CAAC,CAAC,CAC3O,CACF,CAEA,IAAI,SAAW,SAAU,KAAM,OAAQ,CACrC,GAAI,KAAI,KAAM,MAAM,EACpB,KAAI,MAAQ,OAAS,aAAe,aAAe,aACnD,IAAI,MAAgC,EAAzB,QAAU,aAAiB,2EAAgF,4DAAN,CAAmE,EACrL,EACI,MAAM,WAAa,SACrB,SAAS,aAAc,EAAE,+DAA+D,CAAC,EACzF,MAAM,KAAK,EAAE,wIAAwI,CAAC,GAC7I,MAAM,WAAa,OAC5B,SAAS,aAAc,EAAE,gEAAgE,CAAC,EAE1F,SAAS,aAAc,EAAE,4DAA4D,CAAC,CAE1F,CACA,GAAI,MAAM,YAAa,CACrB,IAAI,OAAS,gBAAkB,MAAM,gBAAkB,QAAU,aAAe,gBAC5E,gBAAkB,MAAM,gBAAkB,SAAS,MAAM,KAAK,EAAE,6GAA6G,CAAC,EAClL,IAAI,GAAK,IAAI,OAAQ,EAAE,YAAY,MAAM,CAAC,CAAC,EAC3C,GAAI,CAAC,IAAM,CAAC,eAAgB,CAC1B,IAAI,MAAQ,SAAW,aAAe,gBAAkB,aACxD,IAAI,MAAO,EAAE,YAAY,KAAK,CAAC,CAAC,CAClC,CACF,CACA,MAAM,KAAK,EAAE,eAAiB,gCAAkC,kBAAkB,CAAC,EAEnF,IAAI,UAAY,OAAO,OAAO,OAAO,SAAU,EAAG,EAAG,CAAE,OAAO,EAAI,EAAE,EAAI,EAAG,CAAC,CAAC,EACzE,UAAY,GAAG,MAAM,KAAK,EAAE,wJAAyJ,CAAC,EAE1L,IAAI,MAAQ,MAAM,OAAO,SAAU,EAAG,GAAI,CACxC,OAAO,GAAK,GAAG,QAAQ,WAAa,GAAG,QAAU,OAAO,GAAG,QAAQ,KAAK,EAAI,GAAG,SAAW,EAC5F,EAAG,CAAC,EAEJ,MAAO,CACL,YAAa,KACb,eAAgB,UAChB,kBAAmB,KAAK,MAAM,KAAK,IAAI,GAAI,CAAC,UAAY,EAAE,EAAI,GAAG,EACjE,OACA,gBACA,UAAW,MAAQ,KAAO,KAAO,OAAO,KAAO,SAAS,EACxD,UAAW,eAAe,MAAM,OAAO,EACvC,MACA,MACA,MACA,MAAO,OAAO,KAAK,CACrB,CACF,CAEA,SAAS,OAAO,EAAG,CACjB,OAAI,GAAK,KAAa,GACf,IAAI,KAAK,MAAM,EAAI,EAAE,EAAI,EAAE,EAAI,IACxC,CAEA,IAAI,KAAO,CACT,UACA,eACA,mBACA,aACA,qBACA,aACF,EAEA,GAAI,OAAO,OAAW,KAAe,OAAO,QAAS,CACnD,OAAO,QAAU,KACjB,MACF,CAIA,SAAS,IAAI,EAAG,CACd,OAAO,OAAO,GAAY,EAAM,EAAE,QAAQ,WAAY,SAAU,EAAG,CACjE,MAAO,CAAE,IAAK,QAAS,IAAK,OAAQ,IAAK,OAAQ,IAAK,SAAU,IAAK,OAAQ,EAAE,CAAC,CAClF,CAAC,CACH,CAEA,SAAS,MAAM,EAAG,SAAU,CAC1B,GAAI,CAGF,IAAI,KAAO,UAAY,MACvB,GAAI,EAAE,KAAK,IAAM,KAAM,CACrB,IAAI,GAAK,IAAI,KAAK,aAAa,QAAS,CAAE,MAAO,WAAY,SAAU,KAAM,gBAAiB,cAAe,CAAC,EAAE,OAAO,CAAC,EACxH,MAAO,KAAK,KAAK,EAAE,GAAK,KAAK,MAAM,EAAE,IAAM,IAAM,GAAK,OAAW,KAAK,MAAM,EAAG,CAAC,EAAI,GAAK,OAAW,IACtG,CACA,OAAO,IAAI,KAAK,aAAa,QAAS,CAAE,MAAO,WAAY,SAAU,KAAM,gBAAiB,cAAe,CAAC,EAAE,OAAO,CAAC,EAAI,IAAM,IAClI,MAAY,CAAE,OAAO,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAI,KAAO,UAAY,MAAQ,CACzE,CAGA,IAAI,OAAS,CAAE,IAAK,WAAY,IAAK,cAAe,EAAG,SAAU,GAAI,YAAa,IAAK,QAAS,IAAK,MAAO,MAAO,QAAS,IAAK,MAAO,KAAM,OAAQ,IAAK,aAAc,EAEzK,SAAS,SAAS,EAAG,KAAM,MAAO,CAChC,IAAI,GAAK,EAAE,SAAS,IAAI,EACxB,GAAK,GACL,IAAI,GAAG,OAAS,WAAY,CAAE,GAAG,QAAU,QAAU,IAAK,MAAQ,CAClE,GAAI,GAAG,QAAU,CAAC,GAAG,QAAS,CAC5B,QAAS,EAAI,EAAG,EAAI,GAAG,OAAQ,IAAS,GAAG,CAAC,EAAE,QAAU,OAAS,CAAC,GAAG,CAAC,EAAE,QAAQ,UAAU,IAAG,GAAG,CAAC,EAAE,QAAU,IAC7G,MACF,CACA,GAAI,GAAG,QAAS,CAAE,QAAS,EAAI,EAAG,EAAI,GAAG,QAAQ,OAAQ,IAAS,GAAG,QAAQ,CAAC,EAAE,QAAU,QAAO,GAAG,MAAQ,OAAO,MAAQ,CAC3H,GAAI,GAAG,OAAS,QAAS,CACvB,IAAI,EAAI,WAAW,KAAK,EACnB,MAAM,CAAC,IAAG,GAAG,MAAQ,KAAK,IAAI,KAAK,IAAI,EAAG,CAAC,GAAG,GAAG,EAAG,CAAC,GAAG,GAAG,GAChE,MACF,EACF,CAEA,SAAS,YAAY,KAAM,CACzB,IAAI,EAAI,KAAK,cAAc,MAAM,EAC7B,EACJ,GAAI,CAAE,EAAI,IAAI,gBAAgB,OAAO,SAAS,MAAM,CAAG,MAAY,CAAE,MAAO,EAAO,CACnF,IAAI,IAAM,GACV,cAAO,KAAK,MAAM,EAAE,QAAQ,SAAU,EAAG,CAAM,EAAE,IAAI,CAAC,IAAK,SAAS,EAAG,OAAO,CAAC,EAAG,EAAE,IAAI,CAAC,CAAC,EAAG,IAAM,GAAQ,CAAC,EACrG,GACT,CAEA,SAAS,UAAU,KAAM,CACvB,IAAI,EAAI,KAAK,cAAc,MAAM,EAC7B,EAAI,CAAC,EACT,cAAO,KAAK,MAAM,EAAE,QAAQ,SAAU,EAAG,CACvC,IAAI,GAAK,EAAE,SAAS,OAAO,CAAC,CAAC,EAC7B,GAAK,GACL,KAAI,EAAI,GAAG,OAAS,WAAc,GAAG,QAAU,IAAM,IAAO,GAAG,MAC3D,IAAM,IAAM,GAAK,MAAM,EAAE,KAAK,EAAI,IAAM,mBAAmB,CAAC,CAAC,EACnE,CAAC,EACM,EAAE,KAAK,GAAG,CACnB,CAEA,SAAS,QAAQ,KAAM,CACrB,IAAI,IAAM,OAAO,SACjB,OAAO,IAAI,OAAS,IAAI,SAAW,IAAM,UAAU,IAAI,EAAI,OAC7D,CAEA,SAAS,SAAS,KAAM,CACtB,IAAI,EAAI,KAAK,cAAc,MAAM,EAC7B,IAAM,SAAU,EAAG,CAAE,IAAI,GAAK,EAAE,SAAS,CAAC,EAAG,OAAO,GAAK,GAAG,MAAQ,EAAI,EACxE,QAAU,SAAU,EAAG,CAAE,IAAI,GAAK,EAAE,SAAS,CAAC,EAAG,MAAO,CAAC,EAAE,IAAM,GAAG,QAAU,EAClF,MAAO,CACL,SAAU,IAAI,UAAU,EACxB,YAAa,IAAI,aAAa,EAC9B,QAAS,WAAW,IAAI,QAAQ,CAAC,GAAK,EACtC,KAAM,WAAW,IAAI,KAAK,CAAC,GAAK,EAChC,iBAAkB,IAAI,WAAW,EACjC,MAAO,IAAI,OAAO,EAClB,aAAc,IAAI,OAAO,EACzB,YAAa,QAAQ,aAAa,EAClC,YAAa,IAAI,KAAK,IAAM,OAC5B,cAAe,IAAI,MAAM,CAC3B,CACF,CAEA,SAAS,eAAe,KAAM,MAAO,CACnC,IAAI,QAAU,MAAM,WAAa,SAC7B,gBAAkB,SAAW,MAAM,WAAa,QAChD,QAAU,iBAAmB,MAAM,mBAAqB,UACxD,KAAO,SAAU,IAAK,GAAI,CAAE,KAAK,iBAAiB,GAAG,EAAE,QAAQ,SAAU,GAAI,CAAE,GAAG,OAAS,CAAC,EAAI,CAAC,CAAG,EACxG,KAAK,wBAAyB,OAAO,EACrC,KAAK,2BAA4B,eAAe,EAChD,KAAK,gCAAiC,SAAW,CAAC,MAAM,WAAW,EACnE,KAAK,0BAA2B,SAAW,CAAC,OAAO,EACnD,KAAK,qBAAsB,MAAM,WAAW,EAC5C,IAAI,GAAK,KAAK,cAAc,qBAAqB,EAC7C,KAAI,GAAG,YAAc,MAAM,QAAU,MACzC,IAAI,GAAK,KAAK,cAAc,kBAAkB,EAC1C,KAAI,GAAG,YAAc,MAAM,KAAO,KACxC,CAGA,SAAS,iBAAiB,KAAM,QAAS,SAAU,CACjD,IAAI,WAAa,GACjB,KAAK,iBAAiB,qBAAqB,EAAE,QAAQ,SAAU,MAAO,CACpE,IAAI,KAAO,MAAM,aAAa,mBAAmB,EAC7C,EAAI,YAAY,QAAS,IAAI,EAC7B,EAAI,GAAK,sBAAsB,CAAC,EAEpC,GADA,MAAM,OAAS,CAAC,EACZ,EAAG,CACL,WAAa,GACb,IAAI,MAAQ,MAAM,cAAc,cAAc,EAC1C,QAAO,MAAM,YAAc,MAAM,EAAE,MAAO,QAAQ,EACxD,CACF,CAAC,EAED,IAAI,KAAO,KAAK,cAAc,iBAAiB,EAC3C,OAAM,KAAK,OAAS,CAAC,YAEzB,IAAI,KAAO,KAAK,cAAc,qBAAqB,EAC/C,OAAM,KAAK,OAAS,CAAC,YACzB,IAAI,EAAI,KAAK,cAAc,MAAM,EAC7B,CAAC,YAAc,EAAE,SAAS,KAAK,SAAS,EAAG,MAAO,MAAM,EAC5D,IAAI,KAAO,EAAE,SAAS,KACtB,GAAI,MAAQ,KAAK,OAAQ,CACvB,IAAI,IAAM,MAAM,UAAU,KAAK,KAAK,KAAM,SAAU,EAAG,CAAE,OAAO,EAAE,OAAS,CAAC,EAC5E,GAAI,CAAC,KAAO,IAAI,QAAQ,UAAU,EAAG,CACnC,IAAI,MAAQ,MAAM,UAAU,KAAK,KAAK,KAAM,SAAU,EAAG,CAAE,MAAO,CAAC,EAAE,QAAQ,UAAU,CAAG,CAAC,EACvF,QAAO,MAAM,QAAU,GAC7B,CACF,CACF,CAEA,SAAS,SAAS,MAAO,CACvB,MAAO,CAAC,MAAM,SAAU,MAAM,iBAAkB,MAAM,MAAO,MAAM,WAAW,EAAE,KAAK,GAAG,CAC1F,CAOA,SAAS,YAAY,KAAM,MAAO,EAAG,QAAS,CAC5C,IAAI,KAAO,KAAK,cAAc,gBAAgB,EAC9C,GAAI,GAAC,MAAQ,CAAC,OAAO,aACrB,KAAI,IAAM,SAAS,cAAc,KAAK,EACtC,IAAI,UAAY,OAAO,YAAY,KAAK,MAAO,CAAC,EAChD,IAAI,KAAO,IAAI,WACX,IAAM,SAAS,KAAK,EACpB,aAAe,KAAK,cAAgB,IACxC,KAAK,YAAc,IACnB,IAAI,KAAO,KAAK,iBAAiB,KAAK,EACtC,GAAI,CAAC,SAAW,CAAC,KAAK,OAAQ,CAC5B,KAAK,QAAQ,SAAU,GAAI,CAAE,GAAG,OAAO,CAAG,CAAC,EACvC,SAAS,KAAK,UAAU,IAAI,YAAY,EAC5C,KAAK,YAAY,IAAI,EACrB,MACF,CACA,GAAI,aAAc,CAEhB,QAAS,EAAI,EAAG,EAAI,KAAK,OAAS,EAAG,IAAK,KAAK,CAAC,EAAE,OAAO,EACzD,IAAI,MAAQ,KAAK,KAAK,OAAS,CAAC,EAChC,MAAM,UAAU,OAAO,SAAS,EAChC,KAAK,UAAU,IAAI,cAAe,SAAS,EAC3C,KAAK,YAAY,IAAI,EACrB,KAAK,iBAAiB,eAAgB,SAAS,KAAK,EAAG,CACjD,EAAE,SAAW,OACjB,KAAK,oBAAoB,eAAgB,IAAI,EACzC,MAAM,YAAY,MAAM,OAAO,EACnC,KAAK,UAAU,OAAO,SAAS,EACjC,CAAC,CACH,MACE,KAAK,QAAQ,SAAU,GAAI,CAAE,GAAG,OAAO,CAAG,CAAC,EAC3C,KAAK,UAAU,IAAI,YAAY,EAC/B,KAAK,YAAY,IAAI,EAEzB,CAEA,SAAS,OAAO,KAAM,QAAS,SAAU,QAAS,CAChD,IAAI,MAAQ,SAAS,IAAI,EACzB,eAAe,KAAM,KAAK,EAC1B,IAAI,EAAI,UAAU,MAAO,OAAO,EAChC,YAAY,KAAM,MAAO,EAAG,OAAO,EACnC,IAAI,IAAM,KAAK,cAAc,oBAAoB,EAC7C,SAAW,SAAS,SAExB,GAAI,SAAS,SAAW,OAAO,SAAW,OAAO,QAAQ,aACvD,GAAI,CAAE,OAAO,QAAQ,aAAa,OAAO,QAAQ,MAAO,GAAI,OAAO,SAAS,SAAW,IAAM,UAAU,IAAI,EAAI,OAAO,SAAS,IAAI,CAAG,MAAY,CAAe,CAGnK,IAAI,KAAO,EAAE,MAAM,IAAI,SAAU,GAAI,EAAG,CACtC,IAAI,EAAI,GAAG,QACP,OAAS,GAAG,SAAW,GAAG,QAAQ,OAAS,GAAG,QAAQ,QAAU,gBAAkB,IAAI,GAAG,QAAQ,KAAK,EAAI,GAC1G,QAAU,EAAE,MAAQ,KAAO,0BAA4B,IAAI,EAAE,IAAI,EAAI,cAAgB,GACzF,MAAO,kCAAoC,EAAI,GAAK,uEAET,EAAI,yBAA2B,IAAI,EAAE,oBAAqB,CAAE,QAAS,EAAE,KAAM,CAAC,CAAC,EAAI,gDAC1E,EAAI,GAAK,mBAE1D,EAAE,MAAQ,oCAAsC,IAAI,EAAE,KAAK,EAAI,kDAAoD,2DACpH,kEACyC,IAAI,EAAE,GAAG,EAAI,KAAO,IAAI,EAAE,KAAK,EAAI,OAAS,SAClF,OAAS,oCAAsC,OAAS,UAAY,IACrE,6BAA+B,IAAI,GAAG,MAAM,EAAI,4CAEd,GAAG,SAAW,EAAI,GAAG,SAAW,SAAQ,IAAM,MAAM,GAAG,QAAQ,MAAO,QAAQ,EAAI,aAE1H,CAAC,EAAE,KAAK,EAAE,EAEN,SAAW,EAAE,OAAO,IAAI,SAAU,EAAG,CACvC,MAAO,WAAa,IAAI,EAAE,KAAK,EAAI,YAAc,IAAI,EAAE,GAAI,CAAC,EAAI,eAClE,CAAC,EAAE,KAAK,EAAE,EACN,MAAQ,EAAE,MAAM,IAAI,SAAU,EAAG,CAAE,MAAO,OAAS,IAAI,CAAC,EAAI,OAAS,CAAC,EAAE,KAAK,EAAE,EAC/E,UAAY,IAAI,EAAE,cAAc,EAAI,OAAS,EAAE,gBAAkB,IAAM,IAE3E,IAAI,UACF,oDAAsD,IAAI,EAAE,oBAAoB,CAAC,EAAI,4DACvB,EAAE,aAAe,KAAO,SAAM,IAAI,EAAE,WAAW,EAAI,QAAU,yCAA2C,EAAE,kCAAkC,EAAI,sEACjJ,UAAY,yCAA2C,EAAE,eAAe,EAAI,sEAC5E,IAAI,EAAE,SAAS,EAAI,4CAA8C,EAAE,uBAAuB,EAAI,2CAEjI,IAAI,EAAE,mPAAoP,CAAE,EAAG,IAAI,MAAM,OAAO,CAAE,CAAC,CAAC,GAC3S,EAAE,gBAAkB,IAAM,IAAI,EAAE,uBAAwB,CAAE,YAAa,EAAE,eAAgB,CAAC,CAAC,EAAI,IAAM,QACvG,MAAQ,0BAA4B,MAAQ,QAAU,IACvD,uBAAyB,EAAE,YAAY,EAAI,iCAAmC,EAAE,2BAA2B,EAAI,gBAC9G,KAAO,0BAA4B,KAAO,QAAU,wBAA0B,EAAE,gDAAgD,EAAI,QACrI,sEACgD,MAAM,EAAE,MAAO,QAAQ,EAAI,mCAAqC,EAAE,kCAAkC,EAAI,gEACjG,EAAE,MAAM,OAAS,GAAK,aAAe,IAAM,EAAE,sBAAsB,EAAI,qKAG9C,EAAE,0BAA0B,EAAI,oCAAsC,EAAE,kDAAkD,EAAI,oDACrK,EAAE,sCAAsC,EAAI,oCACvD,EAAE,MAAM,IAAI,SAAU,EAAG,CAAE,MAAO,OAAS,IAAI,CAAC,EAAI,OAAS,CAAC,EAAE,KAAK,EAAE,EAAI,wCAClE,SAAW,oCAAsC,EAAE,eAAe,EAAI,YAAc,IAAI,EAAE,eAAgB,CAAC,EAAI,wBAA0B,EAAE,8CAA8C,GAAK,EAAE,gBAAkB,IAAM,EAAE,sBAAsB,EAAI,IAAM,kBAAe,EAAE,mBAAqB,EAAE,KAAK,IAAM,KAAO,QAAY,KAAO,gCACpW,IAAI,EAAE,+UAA2U,CAAC,EAAI,WACrV,EAAE,KAAK,IAAM,KAClB,+LACA,wJAA6I,iBAGrJ,IAAI,iBAAiB,oBAAoB,EAAE,QAAQ,SAAU,IAAK,CAChE,IAAI,iBAAiB,QAAS,UAAY,CACxC,IAAI,GAAK,SAAS,cAAc,MAAM,EACtC,GAAG,UAAY,iBACf,GAAG,aAAa,cAAe,MAAM,EACrC,IAAI,YAAY,EAAE,CACpB,CAAC,CACH,CAAC,EAGD,IAAI,KAAO,KAAK,iBAAiB,oBAAoB,EACjD,IAAM,KAAK,KAAK,OAAS,CAAC,EAC9B,SAAS,QAAQ,EAAG,CAAE,OAAO,IAAM,IAAI,cAAc,uBAAyB,EAAI,IAAI,EAAI,IAAM,CAChG,IAAI,iBAAiB,YAAY,EAAE,QAAQ,SAAU,GAAI,CACvD,IAAI,EAAI,GAAG,aAAa,QAAQ,EAC5B,GAAK,UAAY,CAAE,IAAI,EAAI,QAAQ,CAAC,EAAO,GAAG,EAAE,UAAU,IAAI,QAAQ,CAAG,EACzE,IAAM,UAAY,CAAE,IAAI,EAAI,QAAQ,CAAC,EAAO,GAAG,EAAE,UAAU,OAAO,QAAQ,CAAG,EACjF,GAAG,iBAAiB,aAAc,EAAE,EAAG,GAAG,iBAAiB,aAAc,GAAG,EAC5E,GAAG,iBAAiB,UAAW,EAAE,EAAG,GAAG,iBAAiB,WAAY,GAAG,CACzE,CAAC,EAED,SAAS,UAAW,CAClB,OAAO,EAAE,MAAM,OAAO,SAAU,GAAI,EAAG,CACrC,IAAI,GAAK,IAAI,cAAc,oBAAsB,EAAI,IAAI,EACzD,OAAO,IAAM,GAAG,SAAW,GAAG,OAChC,CAAC,CACH,CAEA,IAAI,iBAAiB,kBAAkB,EAAE,QAAQ,SAAU,GAAI,CAC7D,GAAG,iBAAiB,SAAU,UAAY,CACxC,IAAI,EAAI,OAAO,GAAG,aAAa,WAAW,CAAC,EAAI,EAC3C,EAAI,QAAQ,CAAC,EACb,GAAG,EAAE,UAAU,OAAO,WAAY,CAAC,GAAG,OAAO,EACjD,IAAIC,GAAI,SAAS,EAAE,OAAO,SAAU,EAAG,GAAI,CAAE,OAAO,EAAI,OAAO,GAAG,QAAQ,KAAK,EAAI,GAAG,QAAU,EAAG,CAAC,EACpG,IAAI,cAAc,cAAc,EAAE,YAAc,MAAMA,GAAG,QAAQ,EACjE,IAAI,cAAc,YAAY,EAAE,SAAW,SAAS,EAAE,SAAW,CACnE,CAAC,CACH,CAAC,EAED,IAAI,cAAc,cAAc,EAAE,iBAAiB,QAAS,UAAY,CACtE,IAAI,IAAM,QAAQ,IAAI,EAClB,OAAS,IAAI,cAAc,eAAe,EAC1C,KAAO,UAAY,CAAE,OAAO,YAAc,EAAE,kDAAkD,CAAG,EACjG,OAAO,WAAa,OAAO,UAAU,WAAa,OAAO,UAAU,UAAU,UAC/E,OAAO,UAAU,UAAU,UAAU,GAAG,EAAE,KAAK,KAAM,UAAY,CAAE,OAAO,YAAc,GAAK,CAAC,EAE9F,OAAO,YAAc,GAEzB,CAAC,EAED,IAAI,cAAc,YAAY,EAAE,iBAAiB,QAAS,UAAY,CACpE,IAAI,IAAM,KACN,OAAS,SAAS,EACtB,GAAK,OAAO,OACZ,KAAI,OAAS,IAAI,cAAc,eAAe,EAC1C,SAAW,OAAO,SAAW,OAAO,QAAQ,OAAS,OAAO,QAAQ,OAAO,KAAO,IACtF,IAAI,SAAW,GACf,OAAO,YAAc,EAAE,sBAAiB,EACxC,IAAI,KAAO,CAAE,MAAO,OAAO,IAAI,SAAU,GAAI,CAAE,MAAO,CAAE,GAAI,GAAG,QAAQ,GAAI,SAAU,GAAG,QAAS,CAAG,CAAC,CAAE,EACnG,MAAQ,SAAS,WAAa,SAAU,QAAS,CACnD,OAAO,MAAM,SAAW,cAAe,CACrC,OAAQ,OACR,QAAS,CAAE,eAAgB,mBAAoB,OAAQ,kBAAmB,EAC1E,KAAM,KAAK,UAAU,OAAO,CAC9B,CAAC,EAAE,KAAK,SAAU,IAAK,CACrB,OAAO,IAAI,KAAK,EAAE,KAAK,SAAU,EAAG,CAClC,GAAI,CAAC,IAAI,GAAI,MAAM,IAAI,MAAM,EAAE,aAAe,EAAE,uBAAuB,CAAC,EACxE,OAAO,CACT,CAAC,CACH,CAAC,CACH,EACA,QAAQ,QAAQ,MAAM,IAAI,CAAC,EAAE,KAAK,SAAU,KAAM,CAChD,OAAO,YAAc,EAAE,KAAK,IAAM,KAC9B,EAAE,kCAAmC,CAAE,EAAG,OAAO,MAAO,CAAC,EACzD,SAAW,OAAO,OAAS,SAAW,OAAO,OAAS,EAAI,IAAM,IAAM,iBAEtE,OAAO,OAAO,SAAY,YAAc,OAAO,gBACjD,OAAO,QAAQ,OAAO,eAAe,WAAY,CAAE,OAAQ,mBAAoB,SAAU,IAAK,CAAC,EAEjG,SAAS,cAAc,IAAI,YAAY,cAAe,CAAE,QAAS,GAAM,OAAQ,CAAE,OAAQ,mBAAoB,KAAM,IAAK,CAAE,CAAC,CAAC,EACxH,SAAS,SAAU,OAAO,SAAS,KAAO,SAAW,OACpD,IAAI,SAAW,EACtB,CAAC,EAAE,MAAM,SAAU,IAAK,CACtB,OAAO,YAAc,EAAE,wEAAyE,CAAE,MAAO,IAAI,OAAQ,CAAC,EACtH,IAAI,SAAW,EACjB,CAAC,EACH,CAAC,CACH,CAEA,SAAS,MAAM,KAAM,CACnB,GAAI,MAAK,OACT,MAAK,OAAS,GACd,EAAE,QAAQ,KAAK,aAAa,aAAa,GAAK,SAAS,gBAAgB,IAAI,EAC3E,IAAI,MAAQ,KAAK,cAAc,2BAA2B,EACtD,QAAU,CAAC,EACf,GAAI,CAAE,QAAU,MAAQ,KAAK,MAAM,MAAM,WAAW,EAAI,CAAC,CAAG,MAAY,CAAE,QAAU,CAAC,CAAG,CACxF,IAAI,WAAa,CAAC,EAAE,OAAO,SAAW,OAAO,QAAQ,YACjD,SAAW,CACb,SAAU,KAAK,aAAa,eAAe,GAAK,MAChD,SAAU,KAAK,aAAa,iBAAiB,IAAM,OACnD,QAAS,CAAC,YAAc,KAAK,aAAa,eAAe,IAAM,QAC/D,UAAW,OAAO,eACpB,EACI,KAAO,KAAK,cAAc,MAAM,EACpC,YAAY,IAAI,EAChB,iBAAiB,KAAM,QAAS,SAAS,QAAQ,EAEjD,KAAK,iBAAiB,QAAS,SAAU,EAAG,CAAM,EAAE,OAAO,OAAS,SAAS,OAAO,KAAM,QAAS,SAAU,EAAK,CAAG,CAAC,EACtH,KAAK,iBAAiB,SAAU,SAAU,EAAG,CAAE,OAAO,KAAM,QAAS,SAAU,EAAE,OAAO,OAAS,OAAO,CAAG,CAAC,EAC5G,KAAK,iBAAiB,SAAU,SAAU,EAAG,CAAE,EAAE,eAAe,CAAG,CAAC,EACpE,OAAO,KAAM,QAAS,SAAU,EAAI,EACtC,CAEA,SAAS,MAAO,CAAE,SAAS,iBAAiB,aAAa,EAAE,QAAQ,KAAK,CAAG,CAC3E,OAAO,eAAiB,KACpB,SAAS,aAAe,UAAW,SAAS,iBAAiB,mBAAoB,IAAI,EACpF,KAAK,EACV,SAAS,iBAAiB,uBAAwB,IAAI,CACxD,GAAG,OAAO,OAAW,IAAc,OAAS,UAAU,CAGpD,OAAQ,EAAG,CAAE,QAAQ,MAAM,CAAC,CAAG,CACjC,GAAG,CACH,GAAG",
  "names": ["observer", "t"]
}
