{"id":15,"date":"2026-11-01T00:45:39","date_gmt":"2026-10-31T15:45:39","guid":{"rendered":"https:\/\/tools.bl-forest.com\/?page_id=15"},"modified":"2026-11-01T01:43:17","modified_gmt":"2026-10-31T16:43:17","slug":"%e5%9b%9e%e7%b7%9a%e9%80%9f%e5%ba%a6%e6%b8%ac%e5%ae%9a","status":"publish","type":"page","link":"https:\/\/tools.bl-forest.com\/?page_id=15","title":{"rendered":"\u56de\u7dda\u901f\u5ea6\u6e2c\u5b9a"},"content":{"rendered":"\n<style>.subnet-lab-speedtest{max-width:none!important;width:100%;display:block}<\/style>\n<div class=\"subnet-lab-speedtest\"><\/div>\n<script>\n<!--\n\n(function(){const host=document.currentScript.previousElementSibling;if(!host||host.shadowRoot)return;const root=host.attachShadow({mode:\"open\"});root.innerHTML=\"<style>:host{display:block;--blue:#273e8e;--ink:#202d52;--muted:#637785;--line:#dce5e8;color:var(--ink);background:#fff;font-family:Inter,-apple-system,BlinkMacSystemFont,'Segoe UI','Noto Sans JP',sans-serif;font-size:14px}*{box-sizing:border-box}button,a{font:inherit}button{cursor:pointer}button:focus-visible,a:focus-visible{outline:3px solid #4964bc;outline-offset:4px}a{color:var(--blue)}[hidden]{display:none!important}header{max-width:1240px;margin:auto;padding:28px 40px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:26px}.brand{font-weight:850;color:var(--ink);text-decoration:none;font-size:19px;white-space:nowrap}.brand>span:not(.mark){font-weight:400}.mark{display:inline-grid;place-items:center;background:var(--ink);color:#fff;border-radius:8px;width:32px;height:32px;margin-right:8px}.header-note{font-size:10px;letter-spacing:.13em;color:var(--muted)}.badge{margin-left:auto;font-size:11px;color:var(--blue)}main{max-width:1160px;margin:auto;padding:0 24px}.intro{padding:58px 0 36px}.eyebrow{font-size:10px;font-weight:750;letter-spacing:.16em;color:var(--blue);margin:0 0 20px}.eyebrow span{float:right;color:var(--muted)}h1{font-size:43px;line-height:1.4;letter-spacing:.02em;font-weight:750;margin:0 0 26px}h1 em{font-style:normal;color:var(--blue)}.lede{font-size:13px;line-height:1.9;color:var(--muted);margin:0}.workspace{display:grid;grid-template-columns:365px 1fr;gap:26px;align-items:start}.card{border:1px solid var(--line);border-radius:14px;padding:26px}.section-heading{display:flex;gap:10px;align-items:center}.section-heading h2{font-size:15px;margin:0}.step{font:11px monospace;color:var(--blue);background:#edf1fc;border-radius:4px;padding:5px 7px}.tag{margin-left:auto;font-size:10px;border:1px solid var(--line);padding:4px 8px;border-radius:4px;color:var(--muted)}.dial{width:190px;margin:25px auto 8px;text-align:center}.dial svg{width:100%;overflow:visible}.dial path{fill:none;stroke-linecap:round;stroke-width:9}.dial .track{stroke:#edf1fc}.dial .arc{stroke:var(--blue);stroke-dasharray:120 236;opacity:.9}.dial .needle{stroke:var(--blue);stroke-width:4}.dial circle{fill:var(--blue)}.dial span{font:9px monospace;letter-spacing:.13em;color:var(--muted)}.test-mode{text-align:center;font-weight:650;font-size:12px;margin:18px 0}.notice,.privacy{font-size:11px;line-height:1.85;color:var(--muted)}.privacy{font-size:10px}.privacy a{display:inline-block}button{border:0;border-radius:7px;width:100%;padding:15px 12px;background:var(--blue);color:white;font-weight:650;font-size:13px;margin-top:13px}button span{float:right}button:disabled{opacity:.55;cursor:not-allowed}.secondary{background:#fff;color:var(--blue);border:1px solid var(--blue);margin-top:8px}.tiny{text-align:center;color:var(--muted);font-size:10px;margin-bottom:0}.result-heading{margin:3px 0 20px}.metrics{display:grid;grid-template-columns:1fr 1fr;gap:16px}.metric{min-width:0;border:1px solid var(--line);border-radius:12px;padding:24px;background:#fff}.featured{background:#f3f5fc;border-color:#d9dff1}.metric-label{font-size:12px;font-weight:650;color:var(--blue)}.metric p{margin:23px 0 14px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.metric strong{font:500 clamp(28px,3.1vw,44px) monospace;letter-spacing:-.07em;color:var(--blue)}.metric p span{font-size:12px;color:var(--muted)}.metric small{font-size:10px;color:var(--muted)}.latency{grid-column:1\/-1;display:grid;grid-template-columns:1fr auto;align-items:center}.latency p{margin:0}.latency small{grid-column:1\/-1}.latency strong{font-size:32px}.progress-card{margin-top:18px;padding:20px}.progress-label{display:flex;justify-content:space-between;font-size:11px;gap:10px}progress{width:100%;height:7px;margin:16px 0 4px;accent-color:var(--blue)}#status{font-size:11px;line-height:1.8;color:var(--muted);margin-bottom:0}.caption{font-size:10px;line-height:1.9;color:var(--muted);margin:15px 3px}.guide{margin-top:60px;padding:30px 0;border-top:1px solid var(--line)}.guide h2{font-size:17px;margin:0 0 25px}.guide-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:32px}.guide article>span{color:var(--blue);font:10px monospace;letter-spacing:.1em}.guide h3{font-size:13px;margin:12px 0}.guide p{font-size:11px;line-height:1.9;color:var(--muted)}footer{border-top:1px solid var(--line);padding:23px 0 30px;display:flex;justify-content:space-between;gap:12px;font-size:10px;color:var(--muted)}@media(max-width:800px){.workspace{grid-template-columns:1fr}.control{display:block}.dial{margin-top:12px}.metrics{grid-template-columns:1fr 1fr}.guide-grid{gap:20px}.metric strong{font-size:40px}}@media(max-width:520px){header{padding:20px;gap:8px}.header-note{display:none}.badge{font-size:9px}main{padding:0 18px}.intro{padding:38px 0 28px}h1{font-size:33px}.eyebrow span{display:none}.lede{font-size:12px}.card{padding:22px}.metric{padding:18px 14px}.metric strong{font-size:32px}.metric p{gap:5px}.guide{margin-top:36px}.guide-grid{grid-template-columns:1fr;gap:14px}.guide h3{margin:9px 0}.guide p{margin-bottom:0}footer{flex-direction:column}.latency .metric-label{font-size:11px}}\\n.transfer{margin-top:18px;padding:20px;background:#fbfcff}.transfer-heading{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}.transfer-heading h3{font-size:12px;margin:0}.transfer-heading>span{font-size:10px;color:var(--blue);font-weight:650}.transfer-scene{display:grid;grid-template-columns:100px minmax(50px,1fr) 100px;align-items:center;gap:8px;margin:24px 0 18px}.endpoint{text-align:center}.endpoint svg{width:42px;height:42px;display:block;margin:0 auto 7px;fill:none;stroke:var(--blue);stroke-width:2;stroke-linecap:round}.endpoint strong{display:block;font-size:11px}.endpoint small{display:block;font-size:9px;margin-top:3px;color:var(--muted)}.transfer-path{position:relative;height:2px;background:#cdd6ef;margin-top:-20px}.direction-mark{position:absolute;top:-17px;left:0;right:0;text-align:center;color:#8292bc;font-size:24px;line-height:32px;background:#fbfcff;width:30px;margin:auto}.data-dot{display:none;position:absolute;top:-4px;width:10px;height:10px;border-radius:3px;background:var(--blue);box-shadow:0 0 0 4px #edf1fc}.transfer[data-mode=download] .data-dot,.transfer[data-mode=upload] .data-dot,.transfer[data-mode=latency] .dot-one{display:block;animation:flow-up 1.8s linear infinite}.transfer[data-mode=download] .data-dot{animation-name:flow-down}.transfer[data-mode=latency] .dot-one{animation:flow-up 1.5s ease-in-out infinite alternate}.transfer .dot-two{animation-delay:-.6s!important}.transfer .dot-three{animation-delay:-1.2s!important}.transfer[data-mode=download] .direction-mark::before{content:'\u2190'}.transfer[data-mode=upload] .direction-mark::before{content:'\u2192'}.transfer[data-mode=download] .direction-mark,.transfer[data-mode=upload] .direction-mark{font-size:0}.transfer .direction-mark::before{font-size:24px}#request-info{font-size:11px;line-height:1.8;color:var(--blue);margin:0}.motion-note{font-size:9px;line-height:1.7;color:var(--muted);margin:7px 0 0}@keyframes flow-up{from{left:0}to{left:calc(100% - 10px)}}@keyframes flow-down{from{left:calc(100% - 10px)}to{left:0}}.method{margin-top:15px}.method-intro,.method p{font-size:12px;color:var(--muted);line-height:1.9}.method-grid{display:grid;grid-template-columns:1fr 1fr;gap:22px;margin:24px 0}.method-grid article{min-width:0;padding:20px;border:1px solid var(--line);border-radius:10px}.method h3{font-size:13px}.method code{font:11px\/1.8 monospace;overflow-wrap:anywhere;word-break:break-word;color:var(--blue)}.method-grid article>code{display:block;background:#f3f5fc;padding:12px;border-radius:5px}.size-heading{margin-top:28px}.size-table-wrap{border:1px solid var(--line);border-radius:10px;overflow:hidden}.method table{width:100%;border-collapse:collapse;font-size:12px;text-align:left}.method caption{text-align:left;font-size:11px;color:var(--muted);padding:14px 18px;background:#f8f9fd}.method td,.method th{padding:14px 18px;border-top:1px solid var(--line)}.method th{font-weight:600}.method thead th{font-size:11px;color:var(--muted)}.method th small{font-size:10px;font-weight:400;white-space:nowrap}.total-row{background:#f3f5fc;color:var(--blue)}.method .method-note{font-size:11px}.latency-note{border-left:3px solid var(--blue);padding:3px 0 3px 18px;margin:24px 0}.latency-note h3{margin:4px 0}.latency-note p{margin:8px 0}.method .eyebrow{font-size:10px;color:var(--blue)}@media(prefers-reduced-motion:reduce){.transfer .data-dot{animation:none!important}.transfer .dot-one{left:15%}.transfer .dot-two{left:45%}.transfer .dot-three{left:75%}}@media(max-width:520px){.transfer-scene{grid-template-columns:78px minmax(36px,1fr) 78px;gap:5px}.transfer{padding:18px 14px}.transfer-heading>span{font-size:9px}.method-grid{grid-template-columns:1fr;gap:14px}.method-grid article{padding:16px}.method td,.method th{padding:12px 9px;font-size:10px}.method thead th{font-size:9px}.method th small{display:block}.method caption{padding:12px 9px}.method-intro,.method p{font-size:11px}}\\n\/* Prominent consent\/start action only. *\/\\n#start{background:#173574;color:#fff;min-height:56px;padding:18px 16px;font-size:16px;font-weight:800;line-height:1.4;box-shadow:0 3px 8px #00000026}#start:not(:disabled):hover{background:#102650}#start:focus-visible{outline:3px solid #4964bc;outline-offset:4px}#start:disabled{background:#e5e7eb;color:#626974;opacity:1;box-shadow:none;cursor:not-allowed}\\n\\n\/* Keep the longer tool brand readable on narrow screens. *\/\\n@media(max-width:520px){header{flex-wrap:wrap}.badge{margin-left:0}}\\n\\n\\n.guide-grid{grid-template-columns:repeat(2,minmax(0,1fr))}@media(max-width:520px){.guide-grid{grid-template-columns:1fr}}\\n\\n.reference-table-wrap{margin-top:28px;overflow-x:auto;border:1px solid var(--line);border-radius:10px}.reference-table{width:100%;min-width:560px;border-collapse:collapse;text-align:left;font-size:15px;line-height:1.7}.reference-table caption{text-align:left;font-size:16px;font-weight:750;padding:16px 18px;color:var(--ink);background:#f3f5fc}.reference-table th,.reference-table td{padding:16px 18px;border-top:1px solid var(--line)}.reference-table thead{background:#f8f9fd;color:var(--blue)}.reference-table tbody th{font-weight:750}.guide .reference-note{font-size:13px;line-height:1.8;margin-top:14px}@media(max-width:520px){.reference-table{min-width:500px;font-size:14px}.reference-table th,.reference-table td{padding:14px 12px}}\\n\\n.results>.transfer{margin-top:0;margin-bottom:24px}\\n\/* Emphasize measured download\/upload numbers; leave units and latency unchanged. *\/\\n#download,#upload{font-size:clamp(40px,4vw,56px);font-weight:800;max-width:100%;overflow-wrap:anywhere;line-height:1.2}\\n@media(max-width:520px){.metric:not(.latency){grid-column:1\/-1}#download,#upload{font-size:clamp(38px,10vw,48px)}}\\n\\n.reference-table td[data-selected=true]{box-shadow:inset 0 0 0 3px #b91c1c;background:#fff5f5}.result-marker{display:block;margin-top:8px;color:#991b1b;font-size:13px;font-weight:750;overflow-wrap:anywhere;line-height:1.6}.guide>.reference-table-wrap{margin:20px 0 0}.guide>.reference-note{margin-bottom:28px}\\n#cancel{background:#b91c1c;color:#fff;border:1px solid #991b1b;font-weight:800;min-height:48px}#cancel:not([hidden]):not(:disabled){animation:cancel-pulse 2s ease-in-out infinite}#cancel:hover{background:#991b1b}#cancel:focus-visible{outline:3px solid #b91c1c;outline-offset:4px}#cancel:disabled{background:#e5e7eb;color:#626974;border-color:#d1d5db;animation:none}@keyframes cancel-pulse{0%,100%{box-shadow:0 0 0 0 rgba(185,28,28,.12)}50%{box-shadow:0 0 0 6px rgba(185,28,28,.26)}}@media(prefers-reduced-motion:reduce){#cancel:not([hidden]):not(:disabled){animation:none}}#start:not(:disabled){animation:start-pulse 2s ease-in-out infinite}#start:disabled{animation:none}@keyframes start-pulse{0%,100%{box-shadow:0 0 0 0 rgba(23,53,116,.12)}50%{box-shadow:0 0 0 6px rgba(23,53,116,.24)}}@media(prefers-reduced-motion:reduce){#start:not(:disabled){animation:none}}#start:not(:disabled){animation:none;box-shadow:0 0 0 3px rgba(185,28,28,.55),0 0 12px rgba(185,28,28,.3)}#start:disabled{animation:none;box-shadow:none}#start:not(:disabled){animation:start-red-pulse 2s ease-in-out infinite}@keyframes start-red-pulse{0%,100%{box-shadow:0 0 0 1px rgba(185,28,28,.3),0 0 3px rgba(185,28,28,.15)}50%{box-shadow:0 0 0 5px rgba(185,28,28,.65),0 0 16px rgba(185,28,28,.45)}}@media(prefers-reduced-motion:reduce){#start:not(:disabled){animation:none;box-shadow:0 0 0 3px rgba(185,28,28,.55),0 0 12px rgba(185,28,28,.3)}}.start-help{margin-top:24px;padding:18px 20px;border-left:4px solid var(--blue);border-radius:0 8px 8px 0;background:#f3f5fc}.start-help p{font-size:14px;line-height:1.8;margin:0}.start-help p+p{font-size:12px;color:var(--muted);margin-top:6px}header{background:#273e8e;border-bottom-color:#273e8e;color:#fff}header .brand,header .header-note,header .badge{color:#fff}header .mark{background:#fff;color:#273e8e}<\/style><header><a class=\\\"brand\\\" href=\\\"https:\/\/tools.bl-forest.com\/\\\"> <span class=\\\"mark\\\">B<\/span>Blue Forest <span>LAB<\/span><\/a><span class=\\\"header-note\\\">NETWORK TOOLS<\/span><span class=\\\"badge\\\">\u30d6\u30e9\u30a6\u30b6\u30fc\u3067\u6e2c\u5b9a<\/span><\/header>\\n<main><section class=\\\"intro\\\"><p class=\\\"eyebrow\\\">INTERNET SPEED TEST <span>NETWORK \/ 03<\/span><\/p><h1>\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8<br><em>\u56de\u7dda\u901f\u5ea6\u30c6\u30b9\u30c8<\/em><\/h1><p class=\\\"lede\\\">\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u30fb\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u30fb\u5fdc\u7b54\u6642\u9593\u3092\u307e\u3068\u3081\u3066\u78ba\u8a8d\u3002<br>Cloudflare\uff08\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\uff09\u307e\u3067\u306e\u901a\u4fe1\u3067\u6e2c\u5b9a\u3057\u307e\u3059\u3002<\/p><div class=\\\"start-help\\\"><p><strong>\u4e0b\u306e\u300c\u540c\u610f\u3057\u3066\u6e2c\u5b9a\u3059\u308b\u300d\u30dc\u30bf\u30f3\u3092\u62bc\u3059\u3068\u3001\u56de\u7dda\u901f\u5ea6\u306e\u6e2c\u5b9a\u3092\u958b\u59cb\u3057\u307e\u3059\u3002<\/strong><\/p><p>\u901a\u5e38\u306e\u6e2c\u5b9a\u7528\u30c7\u30fc\u30bf\u306f\u5408\u8a08\u7d04101 MB\u3067\u3059\uff08\u901a\u4fe1\u30d8\u30c3\u30c0\u30fc\u7b49\u306f\u5225\u9014\uff09\u3002<\/p><\/div><\/section>\\n<section class=\\\"workspace\\\" aria-label=\\\"\u56de\u7dda\u901f\u5ea6\u6e2c\u5b9a\\\"><div class=\\\"control card\\\"><div class=\\\"section-heading\\\"><span class=\\\"step\\\">01<\/span><h2>\u6e2c\u5b9a\u3092\u306f\u3058\u3081\u308b<\/h2><\/div><div class=\\\"dial\\\" aria-hidden=\\\"true\\\"><svg viewBox=\\\"0 0 200 120\\\"><path class=\\\"track\\\" d=\\\"M25 100 A75 75 0 0 1 175 100\\\"\/><path class=\\\"arc\\\" d=\\\"M25 100 A75 75 0 0 1 175 100\\\"\/><path class=\\\"needle\\\" d=\\\"M100 100 L145 55\\\"\/><circle cx=\\\"100\\\" cy=\\\"100\\\" r=\\\"7\\\"\/><\/svg><span>READY TO CHECK<\/span><\/div><p class=\\\"test-mode\\\">\u30c7\u30fc\u30bf\u91cf\u3092\u6291\u3048\u305f\u7c21\u6613\u6e2c\u5b9a<\/p><p class=\\\"notice\\\">\u958b\u59cb\u3059\u308b\u3068\u5b9f\u969b\u306b\u30c7\u30fc\u30bf\u3092\u9001\u53d7\u4fe1\u3057\u307e\u3059\u3002\u4e88\u5b9a\u306e\u6e2c\u5b9a\u30c7\u30fc\u30bf\u306f\u6700\u5927 <strong>101 MB<\/strong>\uff08\u518d\u8a66\u884c\u3092\u542b\u3080\u8981\u6c42\u91cf\u306f 104 MB \u307e\u3067\uff09\u3002\u901a\u4fe1\u30d8\u30c3\u30c0\u30fc\u7b49\u306e\u5206\u304c\u5225\u9014\u52a0\u308f\u308a\u3001\u5b9f\u969b\u306e\u901a\u4fe1\u91cf\u306f\u5909\u52d5\u3057\u307e\u3059\u3002<\/p><p class=\\\"privacy\\\">\u6e2c\u5b9a\u5148\u306e Cloudflare \u306b IP \u30a2\u30c9\u30ec\u30b9\u306a\u3069\u306e\u901a\u4fe1\u60c5\u5831\u3068\u6e2c\u5b9a\u7528\u30c7\u30fc\u30bf\u304c\u9001\u4fe1\u3055\u308c\u307e\u3059\u3002\u6e2c\u5b9a\u7d50\u679c\u306e\u8ffd\u52a0\u30ed\u30b0\u9001\u4fe1\u306f\u7121\u52b9\u3067\u3059\u3002<a href=\\\"https:\/\/www.cloudflare.com\/privacypolicy\/\\\" target=\\\"_blank\\\" rel=\\\"noopener noreferrer\\\">\u30d7\u30e9\u30a4\u30d0\u30b7\u30fc\u30dd\u30ea\u30b7\u30fc \u2197<\/a><\/p><button id=\\\"start\\\" type=\\\"button\\\">\u540c\u610f\u3057\u3066\u6e2c\u5b9a\u3059\u308b <span aria-hidden=\\\"true\\\">\u2192<\/span><\/button><button id=\\\"cancel\\\" class=\\\"secondary\\\" type=\\\"button\\\" hidden>\u6e2c\u5b9a\u3092\u4e2d\u6b62<\/button><p class=\\\"tiny\\\">\u958b\u59cb\u524d\u306b\u6e2c\u5b9a\u5148\u3078\u306e\u901a\u4fe1\u306f\u884c\u3044\u307e\u305b\u3093\u3002<\/p><\/div>\\n<div class=\\\"results\\\"><section id=\\\"transfer\\\" class=\\\"transfer card\\\" data-mode=\\\"idle\\\" aria-label=\\\"\u9001\u53d7\u4fe1\u306e\u6d41\u308c\\\"><div class=\\\"transfer-heading\\\"><h3>\u30c7\u30fc\u30bf\u306e\u6d41\u308c<\/h3><span id=\\\"transfer-label\\\" role=\\\"status\\\" aria-live=\\\"polite\\\">\u5f85\u6a5f\u4e2d<\/span><\/div><div class=\\\"transfer-scene\\\" aria-hidden=\\\"true\\\"><div class=\\\"endpoint\\\"><svg viewBox=\\\"0 0 48 48\\\"><rect x=\\\"7\\\" y=\\\"7\\\" width=\\\"34\\\" height=\\\"25\\\" rx=\\\"3\\\"\/><path d=\\\"M24 33v8M15 41h18\\\"\/><\/svg><strong>\u3042\u306a\u305f\u306e\u7aef\u672b<\/strong><\/div><div class=\\\"transfer-path\\\"><span class=\\\"direction-mark\\\">\u21c4<\/span><i class=\\\"data-dot dot-one\\\"><\/i><i class=\\\"data-dot dot-two\\\"><\/i><i class=\\\"data-dot dot-three\\\"><\/i><\/div><div class=\\\"endpoint\\\"><svg viewBox=\\\"0 0 48 48\\\"><rect x=\\\"7\\\" y=\\\"6\\\" width=\\\"34\\\" height=\\\"15\\\" rx=\\\"3\\\"\/><rect x=\\\"7\\\" y=\\\"27\\\" width=\\\"34\\\" height=\\\"15\\\" rx=\\\"3\\\"\/><path d=\\\"M13 13h2M13 34h2M22 13h12M22 34h12\\\"\/><\/svg><strong>Cloudflare<\/strong><small>\u6e2c\u5b9a\u30b5\u30fc\u30d0\u30fc<\/small><\/div><\/div><p id=\\\"request-info\\\">\u958b\u59cb\u3059\u308b\u3068\u3001\u73fe\u5728\u306e\u9001\u53d7\u4fe1\u65b9\u5411\u3068\u8981\u6c42\u30c7\u30fc\u30bf\u91cf\u3092\u8868\u793a\u3057\u307e\u3059\u3002<\/p><p class=\\\"motion-note\\\">\u52d5\u304d\u306f\u9001\u53d7\u4fe1\u65b9\u5411\u306e\u30a4\u30e1\u30fc\u30b8\u3067\u3059\u3002\u5b9f\u969b\u306e\u901f\u5ea6\u3084\u30d1\u30b1\u30c3\u30c8\u6570\u3092\u8868\u3059\u3082\u306e\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002<\/p><\/section><div class=\\\"section-heading result-heading\\\"><span class=\\\"step\\\">02<\/span><h2>\u6e2c\u5b9a\u7d50\u679c<\/h2><span id=\\\"state\\\" class=\\\"tag\\\">\u672a\u6e2c\u5b9a<\/span><\/div><div class=\\\"metrics\\\"><article class=\\\"metric featured\\\"><span class=\\\"metric-label\\\">\u2193 \u30c0\u30a6\u30f3\u30ed\u30fc\u30c9<\/span><p><strong id=\\\"download\\\">\u2014<\/strong><span>Mbps<\/span><\/p><small>\u52d5\u753b\u8996\u8074\u30fb\u30d5\u30a1\u30a4\u30eb\u306e\u53d7\u4fe1<\/small><\/article><article class=\\\"metric\\\"><span class=\\\"metric-label\\\">\u2191 \u30a2\u30c3\u30d7\u30ed\u30fc\u30c9<\/span><p><strong id=\\\"upload\\\">\u2014<\/strong><span>Mbps<\/span><\/p><small>\u5199\u771f\u306e\u9001\u4fe1\u30fb\u30d5\u30a1\u30a4\u30eb\u306e\u5171\u6709<\/small><\/article><article class=\\\"metric latency\\\"><span class=\\\"metric-label\\\">\u2194 PING\uff08HTTP\u5fdc\u7b54\u9045\u5ef6\uff09<\/span><p><strong id=\\\"latency\\\">\u2014<\/strong><span>ms<\/span><\/p><small>HTTP\u30d9\u30fc\u30b9\u306e\u63a8\u5b9a\u5024 \/ ICMP Ping\u3067\u306f\u3042\u308a\u307e\u305b\u3093<\/small><\/article><article class=\\\"metric latency\\\"><span class=\\\"metric-label\\\">\u2194 JITTER<\/span><p><strong id=\\\"jitter\\\">\u2014<\/strong><span>ms<\/span><\/p><small>HTTP\u5fdc\u7b54\u9045\u5ef6\u306e\u3070\u3089\u3064\u304d\uff08\u9023\u7d9a\u3059\u308b\u6e2c\u5b9a\u5024\u306e\u5dee\u306e\u7d76\u5bfe\u5024\u306e\u5e73\u5747\uff09\u30022\u4ef6\u672a\u6e80\u306f \u2014\u3002ICMP\u30fbUDP\u306e\u6e2c\u5b9a\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002<\/small><\/article><\/div><div class=\\\"progress-card card\\\"><div class=\\\"progress-label\\\"><span id=\\\"phase\\\">\u6e2c\u5b9a\u306e\u6e96\u5099\u304c\u3067\u304d\u3066\u3044\u307e\u3059<\/span><span id=\\\"elapsed\\\">0 \u79d2<\/span><\/div><progress id=\\\"progress\\\" max=\\\"3\\\" value=\\\"0\\\" aria-label=\\\"\u6e2c\u5b9a\u306e\u9032\u884c\u6bb5\u968e\\\"><\/progress><p id=\\\"status\\\" role=\\\"status\\\" aria-live=\\\"polite\\\">\u307b\u304b\u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3084\u52d5\u753b\u518d\u751f\u3092\u6b62\u3081\u3066\u304b\u3089\u958b\u59cb\u3059\u308b\u3068\u3001\u6bd4\u8f03\u3057\u3084\u3059\u304f\u306a\u308a\u307e\u3059\u3002<\/p><\/div><p class=\\\"caption\\\">\u6e2c\u5b9a\u5148\uff1aCloudflare \uff0f \u6e2c\u5b9a\u65b9\u5f0f\uff1aHTTPS<br>\u3053\u308c\u306f\u77ed\u6642\u9593\u30fb\u5c0f\u5bb9\u91cf\u306e\u53c2\u8003\u5024\u3067\u3059\u3002\u9ad8\u901f\u56de\u7dda\u3067\u306f\u5341\u5206\u306a\u8ca0\u8377\u3092\u304b\u3051\u3089\u308c\u305a\u3001\u901f\u5ea6\u3092\u4f4e\u304f\u8868\u793a\u3057\u305f\u308a\u3001\u5024\u3092\u7b97\u51fa\u3067\u304d\u306a\u3044\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002<\/p><\/div><\/section>\\n<section class=\\\"guide\\\"><h2>\u7d50\u679c\u306e\u898b\u304b\u305f<\/h2><p>\u53c2\u8003\u76ee\u5b89\uff08\u7528\u9014\u30fb\u6e2c\u5b9a\u65b9\u6cd5\u3067\u7570\u306a\u308a\u307e\u3059\uff09\u3002\u901a\u4fe1\u54c1\u8cea\u3092\u4fdd\u8a3c\u3059\u308b\u57fa\u6e96\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002<\/p><div class=\\\"reference-table-wrap\\\" role=\\\"region\\\" aria-label=\\\"PING\u30fbJITTER \u306e\u53c2\u8003\u76ee\u5b89\\\" tabindex=\\\"0\\\"><table class=\\\"reference-table\\\"><caption>PING\u30fbJITTER \u306e\u53c2\u8003\u76ee\u5b89<\/caption><thead><tr><th scope=\\\"col\\\">\u6307\u6a19<\/th><th scope=\\\"col\\\">\u826f\u597d<\/th><th scope=\\\"col\\\">\u6ce8\u610f<\/th><th scope=\\\"col\\\">\u8981\u78ba\u8a8d<\/th><\/tr><\/thead><tbody><tr><th scope=\\\"row\\\">PING<\/th><td id=\\\"ref-ping-0\\\" data-selected=\\\"false\\\">100 ms \u4ee5\u4e0b<span id=\\\"mark-ping-0\\\" class=\\\"result-marker\\\" hidden><\/span><\/td><td id=\\\"ref-ping-1\\\" data-selected=\\\"false\\\">100 ms \u8d85\u301c200 ms \u4ee5\u4e0b<span id=\\\"mark-ping-1\\\" class=\\\"result-marker\\\" hidden><\/span><\/td><td id=\\\"ref-ping-2\\\" data-selected=\\\"false\\\">200 ms \u8d85<span id=\\\"mark-ping-2\\\" class=\\\"result-marker\\\" hidden><\/span><\/td><\/tr><tr><th scope=\\\"row\\\">JITTER<\/th><td id=\\\"ref-jitter-0\\\" data-selected=\\\"false\\\">20 ms \u4ee5\u4e0b<span id=\\\"mark-jitter-0\\\" class=\\\"result-marker\\\" hidden><\/span><\/td><td id=\\\"ref-jitter-1\\\" data-selected=\\\"false\\\">20 ms \u8d85\u301c40 ms \u4ee5\u4e0b<span id=\\\"mark-jitter-1\\\" class=\\\"result-marker\\\" hidden><\/span><\/td><td id=\\\"ref-jitter-2\\\" data-selected=\\\"false\\\">40 ms \u8d85<span id=\\\"mark-jitter-2\\\" class=\\\"result-marker\\\" hidden><\/span><\/td><\/tr><\/tbody><\/table><\/div><p class=\\\"reference-note\\\">\u53c2\u8003\u76ee\u5b89\uff08\u7528\u9014\u30fb\u6e2c\u5b9a\u65b9\u6cd5\u3067\u7570\u306a\u308a\u307e\u3059\uff09\u3002\u901a\u4fe1\u54c1\u8cea\u3092\u4fdd\u8a3c\u3059\u308b\u57fa\u6e96\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002HTTP \u5fdc\u7b54\u306b\u57fa\u3065\u304f\u5024\u3067\u3001ICMP\u30fbUDP \u306e\u6e2c\u5b9a\u3068\u306f\u7570\u306a\u308a\u307e\u3059\u3002<\/p><div class=\\\"guide-grid\\\"><article><span>01 \/ DOWNLOAD<\/span><h3>\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\uff1a\u53d7\u3051\u53d6\u308b\u901f\u3055<\/h3><p>\u52d5\u753b\u30fb\u97f3\u58f0\u30fb\u30d5\u30a1\u30a4\u30eb\u306a\u3069\u3092\u53d7\u3051\u53d6\u308b\u901f\u3055\u3067\u3059\u3002Mbps \u306e\u6570\u5024\u304c\u5927\u304d\u3044\u307b\u3069\u30011 \u79d2\u3042\u305f\u308a\u306b\u53d7\u4fe1\u3067\u304d\u308b\u30c7\u30fc\u30bf\u91cf\u304c\u591a\u3044\u76ee\u5b89\u3067\u3059\u3002<\/p><\/article><article><span>02 \/ UPLOAD<\/span><h3>\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\uff1a\u9001\u308a\u51fa\u3059\u901f\u3055<\/h3><p>\u6620\u50cf\u30fb\u97f3\u58f0\u30fb\u30d5\u30a1\u30a4\u30eb\u306a\u3069\u3092\u9001\u308a\u51fa\u3059\u901f\u3055\u3067\u3059\u3002\u30d3\u30c7\u30aa\u901a\u8a71\u3084\u30d5\u30a1\u30a4\u30eb\u5171\u6709\u306a\u3069\u3067\u4f7f\u3044\u307e\u3059\u3002Mbps \u306f MB\/s \u3068\u7570\u306a\u308a\u30018 Mbps \u306f\u7406\u8ad6\u4e0a 1 MB\/s \u306b\u76f8\u5f53\u3057\u307e\u3059\u3002<\/p><\/article><article><span>03 \/ PING<\/span><h3>PING\uff1a\u547c\u3073\u304b\u3051\u304b\u3089\u8fd4\u4e8b\u307e\u3067\u306e\u6642\u9593<\/h3><p>\u5c0f\u3055\u3044\u307b\u3069\u5fdc\u7b54\u304c\u901f\u3044\u76ee\u5b89\u3067\u3059\u3002\u3053\u306e\u30c4\u30fc\u30eb\u3067\u306f HTTP \u5fdc\u7b54\u304b\u3089\u30b5\u30fc\u30d0\u30fc\u51e6\u7406\u6642\u9593\u3092\u5dee\u3057\u5f15\u3044\u305f\u63a8\u5b9a\u5024\u3092\u8868\u793a\u3057\u3001ICMP Ping \u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002<\/p><\/article><article><span>04 \/ JITTER<\/span><h3>JITTER\uff1a\u8fd4\u4e8b\u306e\u901f\u3055\u306e\u3070\u3089\u3064\u304d<\/h3><p>\u5c0f\u3055\u3044\u307b\u3069\u5fdc\u7b54\u6642\u9593\u304c\u5b89\u5b9a\u3057\u3066\u3044\u308b\u76ee\u5b89\u3067\u3059\u3002HTTP \u5fdc\u7b54\u9045\u5ef6\u306e\u9023\u7d9a\u3059\u308b\u6e2c\u5b9a\u5024\u306e\u5dee\u306e\u7d76\u5bfe\u5024\u3092\u5e73\u5747\u3057\u3066\u3044\u307e\u3059\u3002ICMP\u30fbUDP \u306e Jitter \u6e2c\u5b9a\u3068\u306f\u7570\u306a\u308a\u307e\u3059\u3002<\/p><\/article><\/div><p>Wi-Fi \u306e\u8ddd\u96e2\u3001VPN\u3001\u7aef\u672b\u3001\u6642\u9593\u5e2f\u3001\u6df7\u96d1\u3067\u7d50\u679c\u306f\u5909\u308f\u308a\u307e\u3059\u3002\u5951\u7d04\u56de\u7dda\u306e\u6700\u5927\u901f\u5ea6\u3084\u3001\u3059\u3079\u3066\u306e\u63a5\u7d9a\u5148\u3078\u306e\u901f\u5ea6\u3092\u4fdd\u8a3c\u3057\u307e\u305b\u3093\u3002\u300c\u2014\u300d\u306f\u672a\u6e2c\u5b9a\u30fb\u30c7\u30fc\u30bf\u4e0d\u8db3\u306a\u3069\u3092\u8868\u3057\u30010 \u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002<\/p><\/section>\\n<section class=\\\"method guide\\\" aria-labelledby=\\\"method-heading\\\"><p class=\\\"eyebrow\\\">TEST SERVER &amp; DATA<\/p><h2 id=\\\"method-heading\\\">\u3069\u3053\u306b\u3001\u4f55\u3092\u9001\u53d7\u4fe1\u3059\u308b\uff1f<\/h2><p class=\\\"method-intro\\\">\u6e2c\u5b9a\u5148\u306f <strong>Cloudflare \u306e\u901f\u5ea6\u6e2c\u5b9a\u30b5\u30fc\u30d0\u30fc\uff08speed.cloudflare.com\uff09<\/strong>\u3067\u3059\u3002\u3053\u306e\u30b5\u30a4\u30c8\u306e WordPress \u30b5\u30fc\u30d0\u30fc\u3068\u306e\u9593\u306e\u901f\u5ea6\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u7279\u5b9a\u306e\u30b5\u30fc\u30d0\u30fc\u6240\u5728\u5730\u3092\u6307\u5b9a\u3059\u308b\u6e2c\u5b9a\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002<\/p><div class=\\\"method-grid\\\"><article><h3>\u2193 \u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u5148<\/h3><code>https:\/\/speed.cloudflare.com\/__down?bytes=100000<\/code><p>HTTPS GET \u3067\u6e2c\u5b9a\u7528\u30c7\u30fc\u30bf\u3092\u53d7\u4fe1\u3057\u307e\u3059\u3002<code>bytes<\/code> \u306f\u8981\u6c42\u30b5\u30a4\u30ba\u3067\u3001100000\u30fb1000000\u30fb5000000\u30fb20000000 \u306b\u5207\u308a\u66ff\u308f\u308a\u307e\u3059\u3002\u56fa\u5b9a\u306e\u4fdd\u5b58\u30d5\u30a1\u30a4\u30eb\u540d\u306f\u3042\u308a\u307e\u305b\u3093\u3002<code>__down<\/code> \u306f\u6e2c\u5b9a\u7528\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u540d\u3067\u3059\u3002<\/p><\/article><article><h3>\u2191 \u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u5148<\/h3><code>https:\/\/speed.cloudflare.com\/__up<\/code><p>HTTPS POST \u3067\u3001\u30d6\u30e9\u30a6\u30b6\u30fc\u5185\u3067\u751f\u6210\u3057\u305f\u6587\u5b57\u300c0\u300d\u306e\u7e70\u308a\u8fd4\u3057\u3092\u9001\u4fe1\u3057\u307e\u3059\u3002\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u3076\u65b9\u5f0f\u3067\u306f\u306a\u304f\u3001\u30d5\u30a1\u30a4\u30eb\u540d\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u7aef\u672b\u5185\u306e\u5199\u771f\u30fb\u6587\u66f8\u306a\u3069\u306f\u8aad\u307f\u53d6\u308a\u307e\u305b\u3093\u3002<\/p><\/article><\/div><h3 class=\\\"size-heading\\\">\u9001\u53d7\u4fe1\u3059\u308b\u30b5\u30a4\u30ba\u3068\u56de\u6570<\/h3><div class=\\\"size-table-wrap\\\"><table><caption>\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u30fb\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3068\u3082\u306b\u540c\u3058\u69cb\u6210<\/caption><thead><tr><th scope=\\\"col\\\">1 \u56de\u306e\u6e2c\u5b9a\u30c7\u30fc\u30bf<\/th><th scope=\\\"col\\\">\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9<\/th><th scope=\\\"col\\\">\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9<\/th><\/tr><\/thead><tbody><tr><th scope=\\\"row\\\">100,000 \u30d0\u30a4\u30c8 <small>\uff080.1 MB\uff09<\/small><\/th><td>5 \u56de<\/td><td>5 \u56de<\/td><\/tr><tr><th scope=\\\"row\\\">1,000,000 \u30d0\u30a4\u30c8 <small>\uff081 MB\uff09<\/small><\/th><td>5 \u56de<\/td><td>5 \u56de<\/td><\/tr><tr><th scope=\\\"row\\\">5,000,000 \u30d0\u30a4\u30c8 <small>\uff085 MB\uff09<\/small><\/th><td>5 \u56de<\/td><td>5 \u56de<\/td><\/tr><tr><th scope=\\\"row\\\">20,000,000 \u30d0\u30a4\u30c8 <small>\uff0820 MB\uff09<\/small><\/th><td>1 \u56de<\/td><td>1 \u56de<\/td><\/tr><tr class=\\\"total-row\\\"><th scope=\\\"row\\\">\u4e88\u5b9a\u30c7\u30fc\u30bf\u91cf<\/th><td>50.5 MB<\/td><td>50.5 MB<\/td><\/tr><\/tbody><\/table><\/div><p class=\\\"method-note\\\">\u5408\u8a08 <strong>101 MB<\/strong>\u30021 MB = 1,000,000 \u30d0\u30a4\u30c8\u3067\u8a08\u7b97\u3057\u3066\u3044\u307e\u3059\u3002\u56de\u7dda\u72b6\u6cc1\u306b\u3088\u308a\u5927\u304d\u3044\u30b5\u30a4\u30ba\u306e\u6e2c\u5b9a\u3092\u7701\u7565\u3057\u3066\u7d42\u4e86\u3059\u308b\u3053\u3068\u304c\u3042\u308a\u3001\u5b9f\u969b\u306e\u901a\u4fe1\u91cf\u306f\u5909\u308f\u308a\u307e\u3059\u3002<\/p><div class=\\\"latency-note\\\"><h3>\u2194 PING\uff08HTTP\u5fdc\u7b54\u9045\u5ef6\uff09\u306e\u6e2c\u5b9a<\/h3><p><code>https:\/\/speed.cloudflare.com\/__down?bytes=0<\/code> \u306b 5 \u56de\u30a2\u30af\u30bb\u30b9\u3057\u307e\u3059\u3002\u6e2c\u5b9a\u7528\u672c\u6587\u306f 0 \u30d0\u30a4\u30c8\u3067\u3059\u304c\u3001\u901a\u4fe1\u30d8\u30c3\u30c0\u30fc\u7b49\u306f\u767a\u751f\u3057\u307e\u3059\u3002HTTP \u30d9\u30fc\u30b9\u306e\u63a8\u5b9a\u5024\u3067\u3042\u308a\u3001ICMP Ping \u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u5225\u9014\u30a6\u30a9\u30fc\u30e0\u30a2\u30c3\u30d7\u7528\u306e\u30d5\u30a1\u30a4\u30eb\u306f\u9001\u53d7\u4fe1\u3057\u307e\u305b\u3093\u3002<\/p><\/div><p class=\\\"method-note\\\">\u8981\u6c42\u3059\u308b\u6e2c\u5b9a\u30c7\u30fc\u30bf\u91cf\u306f\u518d\u8a66\u884c\u3092\u542b\u3081 <strong>104 MB \u307e\u3067<\/strong>\u3068\u3057\u3001<strong>90 \u79d2<\/strong>\u3067\u505c\u6b62\u3057\u307e\u3059\u3002HTTP \/ TLS \u7b49\u306e\u30d8\u30c3\u30c0\u30fc\u3084\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u306e\u5fdc\u7b54\u306a\u3069\u304c\u5225\u306b\u52a0\u308f\u308b\u305f\u3081\u3001\u7dcf\u901a\u4fe1\u91cf\u306e\u53b3\u5bc6\u306a\u4e0a\u9650\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u6e2c\u5b9a\u5148\u306b\u306f IP \u30a2\u30c9\u30ec\u30b9\u306a\u3069\u306e\u901a\u4fe1\u60c5\u5831\u3068\u6e2c\u5b9a\u7528\u30c7\u30fc\u30bf\u304c\u9001\u4fe1\u3055\u308c\u307e\u3059\u3002<\/p><\/section><footer><span>Blue Forest LAB \/ Network tools<\/span><span>Engine: <a href=\\\"https:\/\/github.com\/cloudflare\/speedtest\\\" target=\\\"_blank\\\" rel=\\\"noopener noreferrer\\\">Cloudflare Speedtest<\/a> \u00b7 MIT<\/span><\/footer><\/main>\\n\\n\\n\";\n\/* Vendored @cloudflare\/speedtest 1.6.0. MIT license below. Modifications: native fetch dependency injection; tiny compatible helpers for the only dependency APIs used. *\/\n\/*\nMIT License\n\nCopyright (c) 2023 Cloudflare\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and\/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n*\/\nfunction createSpeedEngine(fetch) {\nfunction memoize(fn){const cache=new Map();return function(key){if(!cache.has(key))cache.set(key,fn(key));return cache.get(key)}}\nfunction scaleThreshold(domain,range){return function(value){if(value==null || Number.isNaN(+value))return undefined;let i=0;while(i<domain.length && value>=domain[i])i++;return range[i]}}\n\n\n\n\nfunction _arrayLikeToArray(r, a) {\n  (null == a || a > r.length) && (a = r.length);\n  for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];\n  return n;\n}\nfunction _arrayWithHoles(r) {\n  if (Array.isArray(r)) return r;\n}\nfunction _arrayWithoutHoles(r) {\n  if (Array.isArray(r)) return _arrayLikeToArray(r);\n}\nfunction _assertClassBrand(e, t, n) {\n  if (\"function\" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;\n  throw new TypeError(\"Private element is not present on this object\");\n}\nfunction _assertThisInitialized(e) {\n  if (void 0 === e) throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n  return e;\n}\nfunction _callSuper(t, o, e) {\n  return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));\n}\nfunction _checkPrivateRedeclaration(e, t) {\n  if (t.has(e)) throw new TypeError(\"Cannot initialize the same private elements twice on an object\");\n}\nfunction _classCallCheck(a, n) {\n  if (!(a instanceof n)) throw new TypeError(\"Cannot call a class as a function\");\n}\nfunction _classPrivateFieldGet2(s, a) {\n  return s.get(_assertClassBrand(s, a));\n}\nfunction _classPrivateFieldInitSpec(e, t, a) {\n  _checkPrivateRedeclaration(e, t), t.set(e, a);\n}\nfunction _classPrivateFieldSet2(s, a, r) {\n  return s.set(_assertClassBrand(s, a), r), r;\n}\nfunction _classPrivateMethodInitSpec(e, a) {\n  _checkPrivateRedeclaration(e, a), a.add(e);\n}\nfunction _defineProperties(e, r) {\n  for (var t = 0; t < r.length; t++) {\n    var o = r[t];\n    o.enumerable = o.enumerable || false, o.configurable = true, \"value\" in o && (o.writable = true), Object.defineProperty(e, _toPropertyKey(o.key), o);\n  }\n}\nfunction _createClass(e, r, t) {\n  return r && _defineProperties(e.prototype, r), Object.defineProperty(e, \"prototype\", {\n    writable: false\n  }), e;\n}\nfunction _defineProperty(e, r, t) {\n  return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {\n    value: t,\n    enumerable: true,\n    configurable: true,\n    writable: true\n  }) : e[r] = t, e;\n}\nfunction _get() {\n  return _get = \"undefined\" != typeof Reflect && Reflect.get ? Reflect.get.bind() : function (e, t, r) {\n    var p = _superPropBase(e, t);\n    if (p) {\n      var n = Object.getOwnPropertyDescriptor(p, t);\n      return n.get ? n.get.call(arguments.length < 3 ? e : r) : n.value;\n    }\n  }, _get.apply(null, arguments);\n}\nfunction _getPrototypeOf(t) {\n  return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {\n    return t.__proto__ || Object.getPrototypeOf(t);\n  }, _getPrototypeOf(t);\n}\nfunction _inherits(t, e) {\n  if (\"function\" != typeof e && null !== e) throw new TypeError(\"Super expression must either be null or a function\");\n  t.prototype = Object.create(e && e.prototype, {\n    constructor: {\n      value: t,\n      writable: true,\n      configurable: true\n    }\n  }), Object.defineProperty(t, \"prototype\", {\n    writable: false\n  }), e && _setPrototypeOf(t, e);\n}\nfunction _isNativeReflectConstruct() {\n  try {\n    var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));\n  } catch (t) {}\n  return (_isNativeReflectConstruct = function () {\n    return !!t;\n  })();\n}\nfunction _iterableToArray(r) {\n  if (\"undefined\" != typeof Symbol && null != r[Symbol.iterator] || null != r[\"@@iterator\"]) return Array.from(r);\n}\nfunction _iterableToArrayLimit(r, l) {\n  var t = null == r ? null : \"undefined\" != typeof Symbol && r[Symbol.iterator] || r[\"@@iterator\"];\n  if (null != t) {\n    var e,\n      n,\n      i,\n      u,\n      a = [],\n      f = true,\n      o = false;\n    try {\n      if (i = (t = t.call(r)).next, 0 === l) {\n        if (Object(t) !== t) return;\n        f = !1;\n      } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);\n    } catch (r) {\n      o = true, n = r;\n    } finally {\n      try {\n        if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;\n      } finally {\n        if (o) throw n;\n      }\n    }\n    return a;\n  }\n}\nfunction _nonIterableRest() {\n  throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\nfunction _nonIterableSpread() {\n  throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\nfunction ownKeys(e, r) {\n  var t = Object.keys(e);\n  if (Object.getOwnPropertySymbols) {\n    var o = Object.getOwnPropertySymbols(e);\n    r && (o = o.filter(function (r) {\n      return Object.getOwnPropertyDescriptor(e, r).enumerable;\n    })), t.push.apply(t, o);\n  }\n  return t;\n}\nfunction _objectSpread2(e) {\n  for (var r = 1; r < arguments.length; r++) {\n    var t = null != arguments[r] ? arguments[r] : {};\n    r % 2 ? ownKeys(Object(t), true).forEach(function (r) {\n      _defineProperty(e, r, t[r]);\n    }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {\n      Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));\n    });\n  }\n  return e;\n}\nfunction _objectWithoutProperties(e, t) {\n  if (null == e) return {};\n  var o,\n    r,\n    i = _objectWithoutPropertiesLoose(e, t);\n  if (Object.getOwnPropertySymbols) {\n    var n = Object.getOwnPropertySymbols(e);\n    for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);\n  }\n  return i;\n}\nfunction _objectWithoutPropertiesLoose(r, e) {\n  if (null == r) return {};\n  var t = {};\n  for (var n in r) if ({}.hasOwnProperty.call(r, n)) {\n    if (-1 !== e.indexOf(n)) continue;\n    t[n] = r[n];\n  }\n  return t;\n}\nfunction _possibleConstructorReturn(t, e) {\n  if (e && (\"object\" == typeof e || \"function\" == typeof e)) return e;\n  if (void 0 !== e) throw new TypeError(\"Derived constructors may only return object or undefined\");\n  return _assertThisInitialized(t);\n}\nfunction set(e, r, t, o) {\n  return set = \"undefined\" != typeof Reflect && Reflect.set ? Reflect.set : function (e, r, t, o) {\n    var f,\n      i = _superPropBase(e, r);\n    if (i) {\n      if ((f = Object.getOwnPropertyDescriptor(i, r)).set) return f.set.call(o, t), true;\n      if (!f.writable) return false;\n    }\n    if (f = Object.getOwnPropertyDescriptor(o, r)) {\n      if (!f.writable) return false;\n      f.value = t, Object.defineProperty(o, r, f);\n    } else _defineProperty(o, r, t);\n    return true;\n  }, set(e, r, t, o);\n}\nfunction _set(e, r, t, o, f) {\n  if (!set(e, r, t, o || e) && f) throw new TypeError(\"failed to set property\");\n  return t;\n}\nfunction _setPrototypeOf(t, e) {\n  return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {\n    return t.__proto__ = e, t;\n  }, _setPrototypeOf(t, e);\n}\nfunction _slicedToArray(r, e) {\n  return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();\n}\nfunction _superPropBase(t, o) {\n  for (; !{}.hasOwnProperty.call(t, o) && null !== (t = _getPrototypeOf(t)););\n  return t;\n}\nfunction _superPropGet(t, o, e, r) {\n  var p = _get(_getPrototypeOf(t.prototype ), o, e);\n  return 2 & r && \"function\" == typeof p ? function (t) {\n    return p.apply(e, t);\n  } : p;\n}\nfunction _superPropSet(t, e, o, r, p, f) {\n  return _set(_getPrototypeOf(t.prototype ), e, o, r, p);\n}\nfunction _toConsumableArray(r) {\n  return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();\n}\nfunction _toPrimitive(t, r) {\n  if (\"object\" != typeof t || !t) return t;\n  var e = t[Symbol.toPrimitive];\n  if (void 0 !== e) {\n    var i = e.call(t, r);\n    if (\"object\" != typeof i) return i;\n    throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n  }\n  return (String )(t);\n}\nfunction _toPropertyKey(t) {\n  var i = _toPrimitive(t, \"string\");\n  return \"symbol\" == typeof i ? i : i + \"\";\n}\nfunction _unsupportedIterableToArray(r, a) {\n  if (r) {\n    if (\"string\" == typeof r) return _arrayLikeToArray(r, a);\n    var t = {}.toString.call(r).slice(8, -1);\n    return \"Object\" === t && r.constructor && (t = r.constructor.name), \"Map\" === t || \"Set\" === t ? Array.from(r) : \"Arguments\" === t || \/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$\/.test(t) ? _arrayLikeToArray(r, a) : void 0;\n  }\n}\n\nvar REL_API_URL = 'https:\/\/speed.cloudflare.com';\nvar defaultConfig = {\n  \/\/ Engine\n  autoStart: true,\n  \/\/ APIs\n  downloadApiUrl: \"\".concat(REL_API_URL, \"\/__down\"),\n  uploadApiUrl: \"\".concat(REL_API_URL, \"\/__up\"),\n  logMeasurementApiUrl: null,\n  logAimApiUrl: 'https:\/\/aim.cloudflare.com\/__log',\n  turnServerUri: 'turn.speed.cloudflare.com:50000',\n  turnServerCredsApiUrl: \"\".concat(REL_API_URL, \"\/turn-creds\"),\n  turnServerUser: null,\n  turnServerPass: null,\n  rpkiInvalidHost: 'invalid.rpki.cloudflare.com',\n  cfTraceUrl: \"\".concat(REL_API_URL, \"\/cdn-cgi\/trace\"),\n  includeCredentials: false,\n  \/\/ Measurements\n  measurements: [{\n    type: 'latency',\n    numPackets: 1\n  },\n  \/\/ initial ttfb estimation\n  {\n    type: 'download',\n    bytes: 1e5,\n    count: 1,\n    bypassMinDuration: true\n  },\n  \/\/ initial download estimation\n  {\n    type: 'latency',\n    numPackets: 20\n  }, {\n    type: 'download',\n    bytes: 1e5,\n    count: 9\n  }, {\n    type: 'download',\n    bytes: 1e6,\n    count: 8\n  }, {\n    type: 'upload',\n    bytes: 1e5,\n    count: 8\n  }, {\n    type: 'packetLoss',\n    numPackets: 1e3,\n    batchSize: 10,\n    batchWaitTime: 10,\n    \/\/ ms (in between batches)\n    responsesWaitTime: 3000 \/\/ ms (silent time after last sent msg)\n  }, {\n    type: 'upload',\n    bytes: 1e6,\n    count: 6\n  }, {\n    type: 'download',\n    bytes: 1e7,\n    count: 6\n  }, {\n    type: 'upload',\n    bytes: 1e7,\n    count: 4\n  }, {\n    type: 'download',\n    bytes: 2.5e7,\n    count: 4\n  }, {\n    type: 'upload',\n    bytes: 2.5e7,\n    count: 4\n  }, {\n    type: 'download',\n    bytes: 1e8,\n    count: 3\n  }, {\n    type: 'upload',\n    bytes: 5e7,\n    count: 3\n  }, {\n    type: 'download',\n    bytes: 2.5e8,\n    count: 2\n  }],\n  measureDownloadLoadedLatency: true,\n  measureUploadLoadedLatency: true,\n  loadedLatencyThrottle: 400,\n  \/\/ ms in between loaded latency requests\n  bandwidthFinishRequestDuration: 1000,\n  \/\/ download\/upload duration (ms) to reach for stopping further measurements\n  estimatedServerTime: 10,\n  \/\/ ms to discount from latency calculation (if not present in response headers)\n\n  \/\/ Result interpretation\n  latencyPercentile: 0.5,\n  \/\/ Percentile used to calculate latency from a set of measurements\n  bandwidthPercentile: 0.9,\n  \/\/ Percentile used to calculate bandwidth from a set of measurements\n  bandwidthMinRequestDuration: 10,\n  \/\/ minimum duration (ms) to consider a measurement good enough to use in bandwidth calculation\n  loadedRequestMinDuration: 250,\n  \/\/ minimum duration (ms) of a request to consider it to be loading the connection\n  loadedLatencyMaxPoints: 20 \/\/ number of data points to keep for loaded latency\n};\n\nvar internalConfig = {\n  \/\/ AIM\n  aimMeasurementScoring: {\n    packetLoss: scaleThreshold([0.01, 0.05, 0.25, 0.5], [10, 5, 0, -10, -20]),\n    latency: scaleThreshold([10, 20, 50, 100, 500], [20, 10, 5, 0, -10, -20]),\n    loadedLatencyIncrease: scaleThreshold([10, 20, 50, 100, 500], [20, 10, 5, 0, -10, -20]),\n    jitter: scaleThreshold([10, 20, 100, 500], [10, 5, 0, -10, -20]),\n    download: scaleThreshold([1e6, 10e6, 50e6, 100e6], [0, 5, 10, 20, 30]),\n    upload: scaleThreshold([1e6, 10e6, 50e6, 100e6], [0, 5, 10, 20, 30])\n  },\n  aimExperiencesDefs: {\n    streaming: {\n      input: ['latency', 'packetLoss', 'download', 'loadedLatencyIncrease'],\n      pointThresholds: [15, 20, 40, 60]\n    },\n    gaming: {\n      input: ['latency', 'packetLoss', 'loadedLatencyIncrease'],\n      pointThresholds: [5, 15, 25, 30]\n    },\n    rtc: {\n      input: ['latency', 'jitter', 'packetLoss', 'loadedLatencyIncrease'],\n      pointThresholds: [5, 15, 25, 40]\n    }\n  }\n};\n\nvar MAX_RETRIES = 20;\nvar ESTIMATED_HEADER_FRACTION = 0.005; \/\/ ~.5% of packet header \/ payload size. used when transferSize is not available.\n\nvar cfGetServerTime = function cfGetServerTime(r) {\n  \/\/ extract server-timing from headers: server-timing: cfRequestDuration;dur=15.999794\n  var serverTiming = r.headers.get(\"server-timing\");\n  if (serverTiming) {\n    var re = serverTiming.match(\/dur=([0-9.]+)\/);\n    if (re) return +re[1];\n  }\n};\nvar getTtfb = function getTtfb(perf) {\n  return perf.responseStart - perf.requestStart;\n};\nvar gePayloadDownload = function gePayloadDownload(perf) {\n  return perf.responseEnd - perf.responseStart;\n}; \/\/ min 1ms\n\nvar calcDownloadDuration = function calcDownloadDuration(_ref) {\n  var ping = _ref.ping,\n    payloadDownloadTime = _ref.payloadDownloadTime;\n  return ping + payloadDownloadTime;\n}; \/\/ request duration excluding server time\n\nvar calcUploadDuration = function calcUploadDuration(_ref2) {\n  var ttfb = _ref2.ttfb;\n  return ttfb;\n};\nvar calcDownloadSpeed = function calcDownloadSpeed(_ref3, numBytes) {\n  var duration = _ref3.duration,\n    transferSize = _ref3.transferSize;\n  \/\/ use transferSize if available. if estimating from numBytes, add ~0.5% of headers.\n  var bits = 8 * (transferSize || +numBytes * (1 + ESTIMATED_HEADER_FRACTION));\n  var secs = duration \/ 1000;\n  return !secs ? undefined : bits \/ secs;\n};\nvar calcUploadSpeed = function calcUploadSpeed(_ref4, numBytes) {\n  var duration = _ref4.duration;\n  var bits = 8 * numBytes * (1 + ESTIMATED_HEADER_FRACTION); \/\/ take into account estimated packet headers\n  var secs = duration \/ 1000; \/\/ subtract estimated server time\n\n  return !secs ? undefined : bits \/ secs;\n};\nvar genContent = memoize(function (numBytes) {\n  return '0'.repeat(numBytes);\n});\n\n\/\/\nvar _qsParams = \/*#__PURE__*\/new WeakMap();\nvar _fetchOptions = \/*#__PURE__*\/new WeakMap();\nvar _responseHook = \/*#__PURE__*\/new WeakMap();\nvar _onRunningChange = \/*#__PURE__*\/new WeakMap();\nvar _onNewMeasurementStarted = \/*#__PURE__*\/new WeakMap();\nvar _onMeasurementResult = \/*#__PURE__*\/new WeakMap();\nvar _onFinished$1 = \/*#__PURE__*\/new WeakMap();\nvar _onConnectionError$1 = \/*#__PURE__*\/new WeakMap();\nvar _measurements = \/*#__PURE__*\/new WeakMap();\nvar _downloadApi = \/*#__PURE__*\/new WeakMap();\nvar _uploadApi = \/*#__PURE__*\/new WeakMap();\nvar _running$2 = \/*#__PURE__*\/new WeakMap();\nvar _finished$1 = \/*#__PURE__*\/new WeakMap();\nvar _results$1 = \/*#__PURE__*\/new WeakMap();\nvar _measIdx = \/*#__PURE__*\/new WeakMap();\nvar _counter = \/*#__PURE__*\/new WeakMap();\nvar _retries = \/*#__PURE__*\/new WeakMap();\nvar _minDuration = \/*#__PURE__*\/new WeakMap();\nvar _throttleMs = \/*#__PURE__*\/new WeakMap();\nvar _estimatedServerTime = \/*#__PURE__*\/new WeakMap();\nvar _currentFetchPromise = \/*#__PURE__*\/new WeakMap();\nvar _currentNextMsmTimeoutId = \/*#__PURE__*\/new WeakMap();\nvar _BandwidthMeasurementEngine_brand = \/*#__PURE__*\/new WeakSet();\nvar BandwidthMeasurementEngine = \/*#__PURE__*\/function () {\n  function BandwidthMeasurementEngine(_measurements2) {\n    var _ref5 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},\n      downloadApiUrl = _ref5.downloadApiUrl,\n      uploadApiUrl = _ref5.uploadApiUrl,\n      _ref5$throttleMs = _ref5.throttleMs,\n      throttleMs = _ref5$throttleMs === void 0 ? 0 : _ref5$throttleMs,\n      _ref5$estimatedServer = _ref5.estimatedServerTime,\n      estimatedServerTime = _ref5$estimatedServer === void 0 ? 0 : _ref5$estimatedServer;\n    _classCallCheck(this, BandwidthMeasurementEngine);\n    \/\/ Internal methods\n    _classPrivateMethodInitSpec(this, _BandwidthMeasurementEngine_brand);\n    _classPrivateFieldInitSpec(this, _qsParams, {});\n    _classPrivateFieldInitSpec(this, _fetchOptions, {});\n    _defineProperty(this, \"finishRequestDuration\", 1000);\n    \/\/ download\/upload duration (ms) to reach for stopping further measurements\n    _defineProperty(this, \"getServerTime\", cfGetServerTime);\n    \/\/ method to extract server time from response\n\n    _classPrivateFieldInitSpec(this, _responseHook, function (r) {\n      return r;\n    });\n    _classPrivateFieldInitSpec(this, _onRunningChange, function () {});\n    _classPrivateFieldInitSpec(this, _onNewMeasurementStarted, function () {});\n    _classPrivateFieldInitSpec(this, _onMeasurementResult, function () {});\n    _classPrivateFieldInitSpec(this, _onFinished$1, function () {});\n    _classPrivateFieldInitSpec(this, _onConnectionError$1, function () {});\n    \/\/ Internal state\n    _classPrivateFieldInitSpec(this, _measurements, void 0);\n    _classPrivateFieldInitSpec(this, _downloadApi, void 0);\n    _classPrivateFieldInitSpec(this, _uploadApi, void 0);\n    _classPrivateFieldInitSpec(this, _running$2, false);\n    _classPrivateFieldInitSpec(this, _finished$1, {\n      down: false,\n      up: false\n    });\n    _classPrivateFieldInitSpec(this, _results$1, {\n      down: {},\n      up: {}\n    });\n    _classPrivateFieldInitSpec(this, _measIdx, 0);\n    _classPrivateFieldInitSpec(this, _counter, 0);\n    _classPrivateFieldInitSpec(this, _retries, 0);\n    _classPrivateFieldInitSpec(this, _minDuration, -Infinity);\n    \/\/ of current measurement\n    _classPrivateFieldInitSpec(this, _throttleMs, 0);\n    _classPrivateFieldInitSpec(this, _estimatedServerTime, 0);\n    _classPrivateFieldInitSpec(this, _currentFetchPromise, undefined);\n    _classPrivateFieldInitSpec(this, _currentNextMsmTimeoutId, undefined);\n    if (!_measurements2) throw new Error('Missing measurements argument');\n    if (!downloadApiUrl) throw new Error('Missing downloadApiUrl argument');\n    if (!uploadApiUrl) throw new Error('Missing uploadApiUrl argument');\n    _classPrivateFieldSet2(_measurements, this, _measurements2);\n    _classPrivateFieldSet2(_downloadApi, this, downloadApiUrl);\n    _classPrivateFieldSet2(_uploadApi, this, uploadApiUrl);\n    _classPrivateFieldSet2(_throttleMs, this, throttleMs);\n    _classPrivateFieldSet2(_estimatedServerTime, this, Math.max(0, estimatedServerTime));\n  }\n\n  \/\/ Public attributes\n  return _createClass(BandwidthMeasurementEngine, [{\n    key: \"results\",\n    get: function get() {\n      \/\/ read access to results\n      return _classPrivateFieldGet2(_results$1, this);\n    }\n  }, {\n    key: \"qsParams\",\n    get:\n    \/\/ additional query string params to include in the requests\n    function get() {\n      return _classPrivateFieldGet2(_qsParams, this);\n    },\n    set: function set(v) {\n      _classPrivateFieldSet2(_qsParams, this, v);\n    }\n  }, {\n    key: \"fetchOptions\",\n    get:\n    \/\/ additional options included in the requests\n    function get() {\n      return _classPrivateFieldGet2(_fetchOptions, this);\n    },\n    set: function set(v) {\n      _classPrivateFieldSet2(_fetchOptions, this, v);\n    }\n  }, {\n    key: \"responseHook\",\n    set:\n    \/\/ pipe-through of response objects\n    function set(f) {\n      _classPrivateFieldSet2(_responseHook, this, f);\n    }\n  }, {\n    key: \"onRunningChange\",\n    set:\n    \/\/ callback invoked when engine starts\/stops\n    function set(f) {\n      _classPrivateFieldSet2(_onRunningChange, this, f);\n    }\n  }, {\n    key: \"onNewMeasurementStarted\",\n    set:\n    \/\/ callback invoked when a new item in the measurement list is started\n    function set(f) {\n      _classPrivateFieldSet2(_onNewMeasurementStarted, this, f);\n    }\n  }, {\n    key: \"onMeasurementResult\",\n    set:\n    \/\/ callback invoked when a new measurement result arrives\n    function set(f) {\n      _classPrivateFieldSet2(_onMeasurementResult, this, f);\n    }\n  }, {\n    key: \"onFinished\",\n    set:\n    \/\/ callback invoked when all the measurements are finished\n    function set(f) {\n      _classPrivateFieldSet2(_onFinished$1, this, f);\n    }\n  }, {\n    key: \"onConnectionError\",\n    set:\n    \/\/ Invoked when unable to get a response from the API\n    function set(f) {\n      _classPrivateFieldSet2(_onConnectionError$1, this, f);\n    }\n\n    \/\/ Public methods\n  }, {\n    key: \"pause\",\n    value: function pause() {\n      clearTimeout(_classPrivateFieldGet2(_currentNextMsmTimeoutId, this));\n      _assertClassBrand(_BandwidthMeasurementEngine_brand, this, _cancelCurrentMeasurement).call(this);\n      _assertClassBrand(_BandwidthMeasurementEngine_brand, this, _setRunning$2).call(this, false);\n    }\n  }, {\n    key: \"play\",\n    value: function play() {\n      if (!_classPrivateFieldGet2(_running$2, this)) {\n        _assertClassBrand(_BandwidthMeasurementEngine_brand, this, _setRunning$2).call(this, true);\n        _assertClassBrand(_BandwidthMeasurementEngine_brand, this, _nextMeasurement).call(this);\n      }\n    }\n  }]);\n}();\nfunction _setRunning$2(running) {\n  var _this = this;\n  if (running !== _classPrivateFieldGet2(_running$2, this)) {\n    _classPrivateFieldSet2(_running$2, this, running);\n    setTimeout(function () {\n      return _classPrivateFieldGet2(_onRunningChange, _this).call(_this, _classPrivateFieldGet2(_running$2, _this));\n    });\n  }\n}\nfunction _saveMeasurementResults(measIdx, measTiming) {\n  var _this2 = this;\n  var _classPrivateFieldGet2$1 = _classPrivateFieldGet2(_measurements, this)[measIdx],\n    bytes = _classPrivateFieldGet2$1.bytes,\n    dir = _classPrivateFieldGet2$1.dir;\n  var results = _classPrivateFieldGet2(_results$1, this);\n  var bytesResult = results[dir].hasOwnProperty(bytes) ? results[dir][bytes] : {\n    timings: [],\n    \/\/ count all measurements with same bytes and direction\n    numMeasurements: _classPrivateFieldGet2(_measurements, this).filter(function (_ref6) {\n      var b = _ref6.bytes,\n        d = _ref6.dir;\n      return bytes === b && dir === d;\n    }).map(function (m) {\n      return m.count;\n    }).reduce(function (agg, cnt) {\n      return agg + cnt;\n    }, 0)\n  };\n  !!measTiming && bytesResult.timings.push(measTiming);\n  bytesResult.timings = bytesResult.timings.slice(-bytesResult.numMeasurements);\n  results[dir][bytes] = bytesResult;\n  if (measTiming) {\n    setTimeout(function () {\n      _classPrivateFieldGet2(_onMeasurementResult, _this2).call(_this2, _objectSpread2({\n        type: dir,\n        bytes: bytes\n      }, measTiming), results);\n    });\n  } else {\n    _classPrivateFieldGet2(_onNewMeasurementStarted, this).call(this, _classPrivateFieldGet2(_measurements, this)[measIdx], results);\n  }\n}\nfunction _nextMeasurement() {\n  var _this3 = this;\n  var measurements = _classPrivateFieldGet2(_measurements, this);\n  var meas = measurements[_classPrivateFieldGet2(_measIdx, this)];\n  if (_classPrivateFieldGet2(_counter, this) >= meas.count) {\n    \/\/ Finished current measurement\n    var finished = _classPrivateFieldGet2(_finished$1, this);\n    if (_classPrivateFieldGet2(_minDuration, this) > this.finishRequestDuration && !meas.bypassMinDuration) {\n      \/\/ mark direction as finished\n      var _dir = meas.dir;\n      _classPrivateFieldGet2(_finished$1, this)[_dir] = true;\n      Object.values(_classPrivateFieldGet2(_finished$1, this)).every(function (finished) {\n        return finished;\n      }) && _classPrivateFieldGet2(_onFinished$1, this).call(this, _classPrivateFieldGet2(_results$1, this));\n    }\n\n    \/\/ clear settings\n    _classPrivateFieldSet2(_counter, this, 0);\n    _classPrivateFieldSet2(_minDuration, this, -Infinity);\n    performance.clearResourceTimings();\n    do {\n      _classPrivateFieldSet2(_measIdx, this, _classPrivateFieldGet2(_measIdx, this) + 1); \/\/ skip through finished measurements\n    } while (_classPrivateFieldGet2(_measIdx, this) < measurements.length && finished[measurements[_classPrivateFieldGet2(_measIdx, this)].dir]);\n    if (_classPrivateFieldGet2(_measIdx, this) >= measurements.length) {\n      \/\/ reached the end: halt further measurements\n      _classPrivateFieldSet2(_finished$1, this, {\n        down: true,\n        up: true\n      });\n      _assertClassBrand(_BandwidthMeasurementEngine_brand, this, _setRunning$2).call(this, false);\n      _classPrivateFieldGet2(_onFinished$1, this).call(this, _classPrivateFieldGet2(_results$1, this));\n      return;\n    }\n    meas = measurements[_classPrivateFieldGet2(_measIdx, this)];\n  }\n  var measIdx = _classPrivateFieldGet2(_measIdx, this);\n  if (_classPrivateFieldGet2(_counter, this) === 0) {\n    _assertClassBrand(_BandwidthMeasurementEngine_brand, this, _saveMeasurementResults).call(this, measIdx); \/\/ register measurement start\n  }\n  var _meas = meas,\n    numBytes = _meas.bytes,\n    dir = _meas.dir;\n  var isDown = dir === 'down';\n  var apiUrl = isDown ? _classPrivateFieldGet2(_downloadApi, this) : _classPrivateFieldGet2(_uploadApi, this);\n  var qsParams = Object.assign({}, _classPrivateFieldGet2(_qsParams, this));\n  isDown && (qsParams.bytes = \"\".concat(numBytes));\n  var url = \"\".concat(apiUrl.startsWith('http') || apiUrl.startsWith('\/\/') ? '' : window.location.origin \/\/ use abs to match perf timing urls\n  ).concat(apiUrl, \"?\").concat(Object.entries(qsParams).map(function (_ref7) {\n    var _ref8 = _slicedToArray(_ref7, 2),\n      k = _ref8[0],\n      v = _ref8[1];\n    return \"\".concat(k, \"=\").concat(v);\n  }).join('&'));\n  var fetchOpt = Object.assign({}, isDown ? {} : {\n    method: 'POST',\n    body: genContent(numBytes)\n  }, _classPrivateFieldGet2(_fetchOptions, this));\n  var serverTime;\n  var curPromise = _classPrivateFieldSet2(_currentFetchPromise, this, fetch(url, fetchOpt).then(function (r) {\n    if (r.ok) return r;\n    throw Error(r.statusText);\n  }).then(function (r) {\n    _this3.getServerTime && (serverTime = _this3.getServerTime(r));\n    return r;\n  }).then(function (r) {\n    return r.text().then(function (body) {\n      _classPrivateFieldGet2(_responseHook, _this3) && _classPrivateFieldGet2(_responseHook, _this3).call(_this3, {\n        url: url,\n        headers: r.headers,\n        body: body\n      });\n      return body;\n    });\n  }).then(function (_, reject) {\n    if (curPromise._cancel) {\n      reject('cancelled');\n      return;\n    }\n    var perf = performance.getEntriesByName(url).slice(-1)[0]; \/\/ get latest perf timing\n    var timing = {\n      transferSize: perf.transferSize,\n      ttfb: getTtfb(perf),\n      payloadDownloadTime: gePayloadDownload(perf),\n      serverTime: serverTime || -1,\n      measTime: new Date()\n    };\n    timing.ping = Math.max(1e-2, timing.ttfb - (serverTime || _classPrivateFieldGet2(_estimatedServerTime, _this3))); \/\/ ttfb = network latency + server time\n\n    timing.duration = (isDown ? calcDownloadDuration : calcUploadDuration)(timing);\n    timing.bps = (isDown ? calcDownloadSpeed : calcUploadSpeed)(timing, numBytes);\n    if (isDown && numBytes) {\n      var reqSize = +numBytes;\n      if (timing.transferSize && (timing.transferSize < reqSize || timing.transferSize \/ reqSize > 1.05)) {\n        \/\/ log if transferSize is too different from requested size\n        console.warn(\"Requested \".concat(reqSize, \"B but received \").concat(timing.transferSize, \"B (\").concat(Math.round(timing.transferSize \/ reqSize * 1e4) \/ 1e2, \"%).\"));\n      }\n    }\n    _assertClassBrand(_BandwidthMeasurementEngine_brand, _this3, _saveMeasurementResults).call(_this3, measIdx, timing);\n    var requestDuration = timing.duration;\n    _classPrivateFieldSet2(_minDuration, _this3, _classPrivateFieldGet2(_minDuration, _this3) < 0 ? requestDuration : Math.min(_classPrivateFieldGet2(_minDuration, _this3), requestDuration)); \/\/ carry minimum request duration\n\n    _classPrivateFieldSet2(_counter, _this3, _classPrivateFieldGet2(_counter, _this3) + 1);\n    _classPrivateFieldSet2(_retries, _this3, 0);\n    if (_classPrivateFieldGet2(_throttleMs, _this3)) {\n      _classPrivateFieldSet2(_currentNextMsmTimeoutId, _this3, setTimeout(function () {\n        return _assertClassBrand(_BandwidthMeasurementEngine_brand, _this3, _nextMeasurement).call(_this3);\n      }, _classPrivateFieldGet2(_throttleMs, _this3)));\n    } else {\n      _assertClassBrand(_BandwidthMeasurementEngine_brand, _this3, _nextMeasurement).call(_this3);\n    }\n  })[\"catch\"](function (error) {\n    var _this$retries, _this$retries2;\n    if (curPromise._cancel) return;\n    console.warn(\"Error fetching \".concat(url, \": \").concat(error));\n    if ((_classPrivateFieldSet2(_retries, _this3, (_this$retries = _classPrivateFieldGet2(_retries, _this3), _this$retries2 = _this$retries++, _this$retries)), _this$retries2) < MAX_RETRIES) {\n      _assertClassBrand(_BandwidthMeasurementEngine_brand, _this3, _nextMeasurement).call(_this3); \/\/ keep trying\n    } else {\n      _classPrivateFieldSet2(_retries, _this3, 0);\n      _assertClassBrand(_BandwidthMeasurementEngine_brand, _this3, _setRunning$2).call(_this3, false);\n      _classPrivateFieldGet2(_onConnectionError$1, _this3).call(_this3, \"Connection failed to \".concat(url, \". Gave up after \").concat(MAX_RETRIES, \" retries.\"));\n    }\n  }));\n}\nfunction _cancelCurrentMeasurement() {\n  var curPromise = _classPrivateFieldGet2(_currentFetchPromise, this);\n  curPromise && (curPromise._cancel = true);\n}\n\nvar _excluded$5 = [\"measureParallelLatency\", \"parallelLatencyThrottleMs\", \"downloadApiUrl\", \"uploadApiUrl\", \"estimatedServerTime\"];\nvar _latencyEngine = \/*#__PURE__*\/new WeakMap();\nvar _latencyTimeout = \/*#__PURE__*\/new WeakMap();\nvar _BandwidthWithParallelLatencyEngine_brand = \/*#__PURE__*\/new WeakSet();\nvar BandwidthWithParallelLatencyEngine = \/*#__PURE__*\/function (_BandwidthEngine) {\n  function BandwidthWithParallelLatencyEngine(measurements) {\n    var _this;\n    var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},\n      _ref$measureParallelL = _ref.measureParallelLatency,\n      measureParallelLatency = _ref$measureParallelL === void 0 ? false : _ref$measureParallelL,\n      _ref$parallelLatencyT = _ref.parallelLatencyThrottleMs,\n      parallelLatencyThrottleMs = _ref$parallelLatencyT === void 0 ? 100 : _ref$parallelLatencyT,\n      downloadApiUrl = _ref.downloadApiUrl,\n      uploadApiUrl = _ref.uploadApiUrl,\n      _ref$estimatedServerT = _ref.estimatedServerTime,\n      estimatedServerTime = _ref$estimatedServerT === void 0 ? 0 : _ref$estimatedServerT,\n      ptProps = _objectWithoutProperties(_ref, _excluded$5);\n    _classCallCheck(this, BandwidthWithParallelLatencyEngine);\n    _this = _callSuper(this, BandwidthWithParallelLatencyEngine, [measurements, _objectSpread2({\n      downloadApiUrl: downloadApiUrl,\n      uploadApiUrl: uploadApiUrl,\n      estimatedServerTime: estimatedServerTime\n    }, ptProps)]);\n    \/\/ Internal methods\n    _classPrivateMethodInitSpec(_this, _BandwidthWithParallelLatencyEngine_brand);\n    \/\/ Internal state\n    _classPrivateFieldInitSpec(_this, _latencyEngine, void 0);\n    _classPrivateFieldInitSpec(_this, _latencyTimeout, void 0);\n    if (measureParallelLatency) {\n      _classPrivateFieldSet2(_latencyEngine, _this, new BandwidthMeasurementEngine([{\n        dir: 'down',\n        bytes: 0,\n        count: Infinity,\n        bypassMinDuration: true\n      }], {\n        downloadApiUrl: downloadApiUrl,\n        uploadApiUrl: uploadApiUrl,\n        estimatedServerTime: estimatedServerTime,\n        throttleMs: parallelLatencyThrottleMs\n      }));\n      _classPrivateFieldGet2(_latencyEngine, _this).qsParams = {\n        during: \"\".concat(measurements[0].dir, \"load\")\n      };\n      _superPropSet((BandwidthWithParallelLatencyEngine), \"onRunningChange\", _assertClassBrand(_BandwidthWithParallelLatencyEngine_brand, _this, _setLatencyRunning), _this, 1);\n      _superPropSet((BandwidthWithParallelLatencyEngine), \"onConnectionError\", function () {\n        return _classPrivateFieldGet2(_latencyEngine, _this).pause();\n      }, _this, 1);\n    }\n    return _this;\n  }\n\n  \/\/ Public attributes\n  _inherits(BandwidthWithParallelLatencyEngine, _BandwidthEngine);\n  return _createClass(BandwidthWithParallelLatencyEngine, [{\n    key: \"latencyResults\",\n    get: function get() {\n      \/\/ read access to latency results\n      return _classPrivateFieldGet2(_latencyEngine, this) && _classPrivateFieldGet2(_latencyEngine, this).results.down[0].timings;\n    }\n\n    \/\/ callback invoked when a new parallel latency result arrives\n  }, {\n    key: \"onParallelLatencyResult\",\n    set: function set(f) {\n      _classPrivateFieldGet2(_latencyEngine, this) && (_classPrivateFieldGet2(_latencyEngine, this).onMeasurementResult = function (res) {\n        return f(res);\n      });\n    }\n\n    \/\/ Overridden attributes\n  }, {\n    key: \"fetchOptions\",\n    get: function get() {\n      return _superPropGet(BandwidthWithParallelLatencyEngine, \"fetchOptions\", this, 1);\n    },\n    set: function set(fetchOptions) {\n      _superPropSet(BandwidthWithParallelLatencyEngine, \"fetchOptions\", fetchOptions, this, 1);\n      _classPrivateFieldGet2(_latencyEngine, this) && (_classPrivateFieldGet2(_latencyEngine, this).fetchOptions = fetchOptions);\n    }\n  }, {\n    key: \"onRunningChange\",\n    set: function set(onRunningChange) {\n      var _this2 = this;\n      _superPropSet(BandwidthWithParallelLatencyEngine, \"onRunningChange\", function (running) {\n        _assertClassBrand(_BandwidthWithParallelLatencyEngine_brand, _this2, _setLatencyRunning).call(_this2, running);\n        onRunningChange(running);\n      }, this, 1);\n    }\n  }, {\n    key: \"onConnectionError\",\n    set: function set(onConnectionError) {\n      var _this3 = this;\n      _superPropSet(BandwidthWithParallelLatencyEngine, \"onConnectionError\", function () {\n        _classPrivateFieldGet2(_latencyEngine, _this3) && _classPrivateFieldGet2(_latencyEngine, _this3).pause();\n        onConnectionError.apply(void 0, arguments);\n      }, this, 1);\n    }\n  }]);\n}(BandwidthMeasurementEngine);\nfunction _setLatencyRunning(running) {\n  var _this4 = this;\n  if (_classPrivateFieldGet2(_latencyEngine, this)) {\n    if (!running) {\n      clearTimeout(_classPrivateFieldGet2(_latencyTimeout, this));\n      _classPrivateFieldGet2(_latencyEngine, this).pause();\n    } else {\n      \/\/ slight delay in starting latency measurements\n      _classPrivateFieldSet2(_latencyTimeout, this, setTimeout(function () {\n        return _classPrivateFieldGet2(_latencyEngine, _this4).play();\n      }, 20));\n    }\n  }\n}\n\nvar _excluded$4 = [\"measurementId\", \"logApiUrl\"];\nvar _measurementId$1 = \/*#__PURE__*\/new WeakMap();\nvar _token = \/*#__PURE__*\/new WeakMap();\nvar _requestTime = \/*#__PURE__*\/new WeakMap();\nvar _logApiUrl = \/*#__PURE__*\/new WeakMap();\nvar _LoggingBandwidthEngine_brand = \/*#__PURE__*\/new WeakSet();\nvar LoggingBandwidthEngine = \/*#__PURE__*\/function (_BandwidthEngine) {\n  function LoggingBandwidthEngine(measurements) {\n    var _this;\n    var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},\n      measurementId = _ref.measurementId,\n      logApiUrl = _ref.logApiUrl,\n      ptProps = _objectWithoutProperties(_ref, _excluded$4);\n    _classCallCheck(this, LoggingBandwidthEngine);\n    _this = _callSuper(this, LoggingBandwidthEngine, [measurements, ptProps]);\n    \/\/ Internal methods\n    _classPrivateMethodInitSpec(_this, _LoggingBandwidthEngine_brand);\n    \/\/ Internal state\n    _classPrivateFieldInitSpec(_this, _measurementId$1, void 0);\n    _classPrivateFieldInitSpec(_this, _token, void 0);\n    _classPrivateFieldInitSpec(_this, _requestTime, void 0);\n    _classPrivateFieldInitSpec(_this, _logApiUrl, void 0);\n    _classPrivateFieldSet2(_measurementId$1, _this, measurementId);\n    _classPrivateFieldSet2(_logApiUrl, _this, logApiUrl);\n    _superPropSet((LoggingBandwidthEngine), \"qsParams\", logApiUrl ? {\n      measId: _classPrivateFieldGet2(_measurementId$1, _this)\n    } : {}, _this, 1);\n    _superPropSet((LoggingBandwidthEngine), \"responseHook\", function (r) {\n      return _assertClassBrand(_LoggingBandwidthEngine_brand, _this, _loggingResponseHook).call(_this, r);\n    }, _this, 1);\n    _superPropSet((LoggingBandwidthEngine), \"onMeasurementResult\", function (meas) {\n      return _assertClassBrand(_LoggingBandwidthEngine_brand, _this, _logMeasurement).call(_this, meas);\n    }, _this, 1);\n    return _this;\n  }\n\n  \/\/ Overridden attributes\n  _inherits(LoggingBandwidthEngine, _BandwidthEngine);\n  return _createClass(LoggingBandwidthEngine, [{\n    key: \"qsParams\",\n    set: function set(qsParams) {\n      _superPropSet(LoggingBandwidthEngine, \"qsParams\", _classPrivateFieldGet2(_logApiUrl, this) ? _objectSpread2({\n        measId: _classPrivateFieldGet2(_measurementId$1, this)\n      }, qsParams) : qsParams, this, 1);\n    }\n  }, {\n    key: \"responseHook\",\n    set: function set(responseHook) {\n      var _this2 = this;\n      _superPropSet(LoggingBandwidthEngine, \"responseHook\", function (r) {\n        responseHook(r);\n        _assertClassBrand(_LoggingBandwidthEngine_brand, _this2, _loggingResponseHook).call(_this2, r);\n      }, this, 1);\n    }\n  }, {\n    key: \"onMeasurementResult\",\n    set: function set(onMeasurementResult) {\n      var _this3 = this;\n      _superPropSet(LoggingBandwidthEngine, \"onMeasurementResult\", function (meas) {\n        for (var _len = arguments.length, restArgs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n          restArgs[_key - 1] = arguments[_key];\n        }\n        onMeasurementResult.apply(void 0, [meas].concat(restArgs));\n        _assertClassBrand(_LoggingBandwidthEngine_brand, _this3, _logMeasurement).call(_this3, meas);\n      }, this, 1);\n    }\n  }]);\n}(BandwidthWithParallelLatencyEngine);\nfunction _loggingResponseHook(r) {\n  if (!_classPrivateFieldGet2(_logApiUrl, this)) return;\n\n  \/\/ get request time\n  _classPrivateFieldSet2(_requestTime, this, +r.headers.get(\"cf-meta-request-time\"));\n\n  \/\/ get token in payload\n  _classPrivateFieldSet2(_token, this, r.body.slice(-300).split('___').pop());\n}\nfunction _logMeasurement(measData) {\n  if (!_classPrivateFieldGet2(_logApiUrl, this)) return;\n  var logData = {\n    type: measData.type,\n    bytes: measData.bytes,\n    ping: Math.round(measData.ping),\n    \/\/ round to ms\n    ttfb: Math.round(measData.ttfb),\n    \/\/ round to ms\n    payloadDownloadTime: Math.round(measData.payloadDownloadTime),\n    duration: Math.round(measData.duration),\n    transferSize: Math.round(measData.transferSize),\n    serverTime: Math.round(measData.serverTime),\n    token: _classPrivateFieldGet2(_token, this),\n    requestTime: _classPrivateFieldGet2(_requestTime, this),\n    measId: _classPrivateFieldGet2(_measurementId$1, this)\n  };\n  _classPrivateFieldSet2(_token, this, null);\n  _classPrivateFieldSet2(_requestTime, this, null);\n  fetch(_classPrivateFieldGet2(_logApiUrl, this), _objectSpread2({\n    method: 'POST',\n    body: JSON.stringify(logData)\n  }, this.fetchOptions));\n}\n\nvar _running$1 = \/*#__PURE__*\/new WeakMap();\nvar _currentPromise = \/*#__PURE__*\/new WeakMap();\nvar _promiseFn = \/*#__PURE__*\/new WeakMap();\nvar _PromiseEngine_brand = \/*#__PURE__*\/new WeakSet();\nvar PromiseEngine = \/*#__PURE__*\/function () {\n  function PromiseEngine(promiseFn) {\n    _classCallCheck(this, PromiseEngine);\n    \/\/ Internal methods\n    _classPrivateMethodInitSpec(this, _PromiseEngine_brand);\n    \/\/ Internal state\n    _classPrivateFieldInitSpec(this, _running$1, false);\n    _classPrivateFieldInitSpec(this, _currentPromise, undefined);\n    _classPrivateFieldInitSpec(this, _promiseFn, void 0);\n    if (!promiseFn) throw new Error(\"Missing operation to perform\");\n    _classPrivateFieldSet2(_promiseFn, this, promiseFn);\n    this.play();\n  }\n\n  \/\/ Public methods\n  return _createClass(PromiseEngine, [{\n    key: \"pause\",\n    value: function pause() {\n      _assertClassBrand(_PromiseEngine_brand, this, _cancelCurrent).call(this);\n      _assertClassBrand(_PromiseEngine_brand, this, _setRunning$1).call(this, false);\n    }\n  }, {\n    key: \"stop\",\n    value: function stop() {\n      this.pause();\n    }\n  }, {\n    key: \"play\",\n    value: function play() {\n      if (!_classPrivateFieldGet2(_running$1, this)) {\n        _assertClassBrand(_PromiseEngine_brand, this, _setRunning$1).call(this, true);\n        _assertClassBrand(_PromiseEngine_brand, this, _next$1).call(this);\n      }\n    }\n  }]);\n}();\nfunction _setRunning$1(running) {\n  if (running !== _classPrivateFieldGet2(_running$1, this)) {\n    _classPrivateFieldSet2(_running$1, this, running);\n  }\n}\nfunction _next$1() {\n  var _this2 = this;\n  var curPromise = _classPrivateFieldSet2(_currentPromise, this, _classPrivateFieldGet2(_promiseFn, this).call(this).then(function () {\n    !curPromise._cancel && _assertClassBrand(_PromiseEngine_brand, _this2, _next$1).call(_this2);\n  }));\n}\nfunction _cancelCurrent() {\n  var curPromise = _classPrivateFieldGet2(_currentPromise, this);\n  curPromise && (curPromise._cancel = true);\n}\nvar _engines = \/*#__PURE__*\/new WeakMap();\nvar LoadNetworkEngine = \/*#__PURE__*\/function () {\n  function LoadNetworkEngine() {\n    var _this = this;\n    var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n      download = _ref.download,\n      upload = _ref.upload;\n    _classCallCheck(this, LoadNetworkEngine);\n    \/\/ Public attributes\n    _defineProperty(this, \"qsParams\", {});\n    \/\/ additional query string params to include in the requests\n    _defineProperty(this, \"fetchOptions\", {});\n    \/\/ Internal state\n    _classPrivateFieldInitSpec(this, _engines, []);\n    \/\/ Expected attrs for each: { apiUrl, chunkSize }\n    if (!download && !upload) throw new Error('Missing at least one of download\/upload config');\n    [[download, 'download'], [upload, 'upload']].filter(function (_ref2) {\n      var _ref3 = _slicedToArray(_ref2, 1),\n        cfg = _ref3[0];\n      return cfg;\n    }).forEach(function (_ref4) {\n      var _ref5 = _slicedToArray(_ref4, 2),\n        cfg = _ref5[0],\n        type = _ref5[1];\n      var apiUrl = cfg.apiUrl,\n        chunkSize = cfg.chunkSize;\n      if (!apiUrl) throw new Error(\"Missing \".concat(type, \" apiUrl argument\"));\n      if (!chunkSize) throw new Error(\"Missing \".concat(type, \" chunkSize argument\"));\n    });\n    var getLoadEngine = function getLoadEngine(_ref6) {\n      var apiUrl = _ref6.apiUrl,\n        _ref6$qsParams = _ref6.qsParams,\n        qsParams = _ref6$qsParams === void 0 ? {} : _ref6$qsParams,\n        _ref6$fetchOptions = _ref6.fetchOptions,\n        fetchOptions = _ref6$fetchOptions === void 0 ? {} : _ref6$fetchOptions;\n      return new PromiseEngine(function () {\n        var fetchQsParams = Object.assign({}, qsParams, _this.qsParams);\n        var url = \"\".concat(apiUrl.startsWith('http') || apiUrl.startsWith('\/\/') ? '' : window.location.origin \/\/ use abs to match perf timing urls\n        ).concat(apiUrl, \"?\").concat(Object.entries(fetchQsParams).map(function (_ref7) {\n          var _ref8 = _slicedToArray(_ref7, 2),\n            k = _ref8[0],\n            v = _ref8[1];\n          return \"\".concat(k, \"=\").concat(v);\n        }).join('&'));\n        var fetchOpt = Object.assign({}, fetchOptions, _this.fetchOptions);\n        return fetch(url, fetchOpt).then(function (r) {\n          if (r.ok) return r;\n          throw Error(r.statusText);\n        }).then(function (r) {\n          return r.text();\n        });\n      });\n    };\n    download && _classPrivateFieldGet2(_engines, this).push(getLoadEngine({\n      apiUrl: download.apiUrl,\n      qsParams: {\n        bytes: \"\".concat(download.chunkSize)\n      }\n    }));\n    upload && _classPrivateFieldGet2(_engines, this).push(getLoadEngine({\n      apiUrl: upload.apiUrl,\n      fetchOptions: {\n        method: 'POST',\n        body: '0'.repeat(upload.chunkSize)\n      }\n    }));\n  }\n  return _createClass(LoadNetworkEngine, [{\n    key: \"pause\",\n    value:\n    \/\/ additional options included in the requests\n\n    \/\/ Public methods\n    function pause() {\n      _classPrivateFieldGet2(_engines, this).forEach(function (engine) {\n        return engine.pause();\n      });\n    }\n  }, {\n    key: \"stop\",\n    value: function stop() {\n      this.pause();\n    }\n  }, {\n    key: \"play\",\n    value: function play() {\n      _classPrivateFieldGet2(_engines, this).forEach(function (engine) {\n        return engine.play();\n      });\n    }\n  }]);\n}();\n\nvar _excluded$3 = [\"iceServers\", \"acceptIceCandidate\", \"dataChannelCfg\"];\nvar _established = \/*#__PURE__*\/new WeakMap();\nvar _sender = \/*#__PURE__*\/new WeakMap();\nvar _receiver = \/*#__PURE__*\/new WeakMap();\nvar _senderDc = \/*#__PURE__*\/new WeakMap();\nvar _receiverDc = \/*#__PURE__*\/new WeakMap();\nvar SelfWebRtcDataConnection = \/*#__PURE__*\/function () {\n  function SelfWebRtcDataConnection() {\n    var _this = this;\n    var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n      _ref$iceServers = _ref.iceServers,\n      iceServers = _ref$iceServers === void 0 ? [] : _ref$iceServers,\n      _ref$acceptIceCandida = _ref.acceptIceCandidate,\n      acceptIceCandidate = _ref$acceptIceCandida === void 0 ? function (candidate) {\n        var protocol = candidate.protocol || '';\n        \/\/ parsed webRTC candidate properties not extracted in Firefox: https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/RTCIceCandidate\n        if (!protocol && candidate.candidate) {\n          var sdpAttrs = candidate.candidate.split(' ');\n          sdpAttrs.length >= 3 && (protocol = sdpAttrs[2]);\n        }\n        return protocol.toLowerCase() === 'udp';\n      } : _ref$acceptIceCandida,\n      _ref$dataChannelCfg = _ref.dataChannelCfg,\n      dataChannelCfg = _ref$dataChannelCfg === void 0 ? {\n        ordered: false,\n        maxRetransmits: 0\n      } : _ref$dataChannelCfg,\n      rtcPeerConnectionCfg = _objectWithoutProperties(_ref, _excluded$3);\n    _classCallCheck(this, SelfWebRtcDataConnection);\n    \/\/ Public attributes\n    _defineProperty(this, \"onOpen\", function () {});\n    \/\/ callback invoked when WebRTC TURN connection is established\n    _defineProperty(this, \"onClose\", function () {});\n    \/\/ callback invoked when WebRTC TURN connection is closed\n    _defineProperty(this, \"onMessageReceived\", function () {});\n    \/\/ Internal state\n    _classPrivateFieldInitSpec(this, _established, false);\n    _classPrivateFieldInitSpec(this, _sender, void 0);\n    _classPrivateFieldInitSpec(this, _receiver, void 0);\n    _classPrivateFieldInitSpec(this, _senderDc, void 0);\n    _classPrivateFieldInitSpec(this, _receiverDc, void 0);\n    var sender = new RTCPeerConnection(_objectSpread2({\n      iceServers: iceServers\n    }, rtcPeerConnectionCfg));\n    var receiver = new RTCPeerConnection(_objectSpread2({\n      iceServers: iceServers\n    }, rtcPeerConnectionCfg));\n    var senderDc = sender.createDataChannel('channel', dataChannelCfg);\n    senderDc.onopen = function () {\n      _classPrivateFieldSet2(_established, _this, true);\n      _this.onOpen();\n    };\n    senderDc.onclose = function () {\n      return _this.close();\n    };\n    \/\/ senderDc.onmessage = msg => this.#onMessage(msg.data);\n\n    receiver.ondatachannel = function (e) {\n      var dc = e.channel;\n      dc.onclose = function () {\n        return _this.close();\n      };\n      dc.onmessage = function (msg) {\n        return _this.onMessageReceived(msg.data);\n      };\n      _classPrivateFieldSet2(_receiverDc, _this, dc);\n    };\n\n    \/\/ sender.onconnectionstatechange = e => console.log('connection state change', e);\n    \/\/ sender.oniceconnectionstatechange = e => console.log('ice connection state change', e);\n    \/\/ sender.onicecandidateerror = e => console.log('ice error', e);\n    sender.onicecandidate = function (e) {\n      \/\/ console.log('sender', e.candidate);\n      e.candidate && acceptIceCandidate(e.candidate) && receiver.addIceCandidate(e.candidate);\n    };\n    receiver.onicecandidate = function (e) {\n      \/\/ console.log('receiver', e.candidate);\n      e.candidate && acceptIceCandidate(e.candidate) && sender.addIceCandidate(e.candidate);\n    };\n    sender.createOffer().then(function (offer) {\n      return sender.setLocalDescription(offer);\n    }).then(function () {\n      return receiver.setRemoteDescription(sender.localDescription);\n    }).then(function () {\n      return receiver.createAnswer();\n    }).then(function (answer) {\n      return receiver.setLocalDescription(answer);\n    }).then(function () {\n      return sender.setRemoteDescription(receiver.localDescription);\n    });\n    _classPrivateFieldSet2(_sender, this, sender);\n    _classPrivateFieldSet2(_receiver, this, receiver);\n    _classPrivateFieldSet2(_senderDc, this, senderDc);\n    _classPrivateFieldSet2(_established, this, false);\n  }\n  return _createClass(SelfWebRtcDataConnection, [{\n    key: \"send\",\n    value:\n    \/\/ callback invoked when a new message is received from the TURN server\n\n    \/\/ Public methods\n    function send(msg) {\n      return _classPrivateFieldGet2(_senderDc, this).send(msg);\n    }\n  }, {\n    key: \"close\",\n    value: function close() {\n      _classPrivateFieldGet2(_sender, this) && _classPrivateFieldGet2(_sender, this).close();\n      _classPrivateFieldGet2(_receiver, this) && _classPrivateFieldGet2(_receiver, this).close();\n      _classPrivateFieldGet2(_senderDc, this) && _classPrivateFieldGet2(_senderDc, this).close();\n      _classPrivateFieldGet2(_receiverDc, this) && _classPrivateFieldGet2(_receiverDc, this).close();\n      _classPrivateFieldGet2(_established, this) && this.onClose();\n      _classPrivateFieldSet2(_established, this, false);\n      return this;\n    }\n  }]);\n}();\n\nvar _onCredentialsFailure = \/*#__PURE__*\/new WeakMap();\nvar _onConnectionError = \/*#__PURE__*\/new WeakMap();\nvar _onFinished = \/*#__PURE__*\/new WeakMap();\nvar _msgTracker = \/*#__PURE__*\/new WeakMap();\nvar _webRtcConnection = \/*#__PURE__*\/new WeakMap();\nvar _numMsgs = \/*#__PURE__*\/new WeakMap();\nvar PacketLossEngine = \/*#__PURE__*\/function () {\n  function PacketLossEngine() {\n    var _this = this;\n    var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n      turnServerUri = _ref.turnServerUri,\n      turnServerCredsApi = _ref.turnServerCredsApi,\n      _ref$turnServerCredsA = _ref.turnServerCredsApiParser,\n      turnServerCredsApiParser = _ref$turnServerCredsA === void 0 ? function (_ref2) {\n        var username = _ref2.username,\n          credential = _ref2.credential,\n          server = _ref2.server;\n        return {\n          turnServerUser: username,\n          turnServerPass: credential,\n          turnServerUri: server\n        };\n      } : _ref$turnServerCredsA,\n      _ref$turnServerCredsA2 = _ref.turnServerCredsApiIncludeCredentials,\n      turnServerCredsApiIncludeCredentials = _ref$turnServerCredsA2 === void 0 ? false : _ref$turnServerCredsA2,\n      turnServerUser = _ref.turnServerUser,\n      turnServerPass = _ref.turnServerPass,\n      _ref$numMsgs = _ref.numMsgs,\n      numMsgs = _ref$numMsgs === void 0 ? 100 : _ref$numMsgs,\n      _ref$batchSize = _ref.batchSize,\n      batchSize = _ref$batchSize === void 0 ? 10 : _ref$batchSize,\n      _ref$batchWaitTime = _ref.batchWaitTime,\n      batchWaitTime = _ref$batchWaitTime === void 0 ? 10 : _ref$batchWaitTime,\n      _ref$responsesWaitTim = _ref.responsesWaitTime,\n      responsesWaitTime = _ref$responsesWaitTim === void 0 ? 5000 : _ref$responsesWaitTim,\n      _ref$connectionTimeou = _ref.connectionTimeout,\n      connectionTimeout = _ref$connectionTimeou === void 0 ? 5000 : _ref$connectionTimeou;\n    _classCallCheck(this, PacketLossEngine);\n    \/\/ Public attributes\n    _classPrivateFieldInitSpec(this, _onCredentialsFailure, function () {});\n    _classPrivateFieldInitSpec(this, _onConnectionError, function () {});\n    _classPrivateFieldInitSpec(this, _onFinished, function () {});\n    _defineProperty(this, \"onMsgSent\", function () {});\n    \/\/ Invoked when sending a new message to the TURN server\n    _defineProperty(this, \"onAllMsgsSent\", function () {});\n    \/\/ Invoked when all messages have been sent\n    _defineProperty(this, \"onMsgReceived\", function () {});\n    \/\/ Public methods\n\n    \/\/ Internal state\n    _classPrivateFieldInitSpec(this, _msgTracker, {});\n    _classPrivateFieldInitSpec(this, _webRtcConnection, void 0);\n    _classPrivateFieldInitSpec(this, _numMsgs, void 0);\n    if (!turnServerUri && !turnServerCredsApi) throw new Error('Missing turnServerCredsApi or turnServerUri argument');\n    if ((!turnServerUser || !turnServerPass) && !turnServerCredsApi) throw new Error('Missing either turnServerCredsApi or turnServerUser+turnServerPass arguments');\n    _classPrivateFieldSet2(_numMsgs, this, numMsgs);\n    (!turnServerUser || !turnServerPass ?\n    \/\/ Get TURN credentials from API endpoint if not statically supplied\n    fetch(turnServerCredsApi, {\n      credentials: turnServerCredsApiIncludeCredentials ? 'include' : undefined\n    }).then(function (r) {\n      return r.json();\n    }).then(function (d) {\n      if (d.error) throw d.error;\n      return d;\n    }).then(turnServerCredsApiParser) : Promise.resolve({\n      turnServerUser: turnServerUser,\n      turnServerPass: turnServerPass\n    }))[\"catch\"](function (e) {\n      return _classPrivateFieldGet2(_onCredentialsFailure, _this).call(_this, e);\n    }).then(function (_ref3) {\n      var turnServerUser = _ref3.turnServerUser,\n        turnServerPass = _ref3.turnServerPass,\n        credsApiTurnServerUri = _ref3.turnServerUri;\n      var c = _classPrivateFieldSet2(_webRtcConnection, _this, new SelfWebRtcDataConnection({\n        iceServers: [{\n          urls: \"turn:\".concat(credsApiTurnServerUri || turnServerUri, \"?transport=udp\"),\n          username: turnServerUser,\n          credential: turnServerPass\n        }],\n        iceTransportPolicy: 'relay'\n      }));\n      var connectionSuccess = false;\n      setTimeout(function () {\n        if (!connectionSuccess) {\n          c.close();\n          _classPrivateFieldGet2(_onConnectionError, _this).call(_this, 'ICE connection timeout!');\n        }\n      }, connectionTimeout);\n      var msgTracker = _classPrivateFieldGet2(_msgTracker, _this);\n      c.onOpen = function () {\n        connectionSuccess = true;\n        var self = _this;\n        (function sendNum(n) {\n          if (n <= numMsgs) {\n            var i = n;\n            while (i <= Math.min(numMsgs, n + batchSize - 1)) {\n              msgTracker[i] = false;\n              c.send(i);\n              self.onMsgSent(i);\n              i++;\n            }\n            setTimeout(function () {\n              return sendNum(i);\n            }, batchWaitTime);\n          } else {\n            self.onAllMsgsSent(Object.keys(msgTracker).length);\n            var finishFn = function finishFn() {\n              c.close();\n              _classPrivateFieldGet2(_onFinished, self).call(self, self.results);\n            };\n            var finishTimeout = setTimeout(finishFn, responsesWaitTime);\n            var missingMsgs = Object.values(_classPrivateFieldGet2(_msgTracker, self)).filter(function (recv) {\n              return !recv;\n            }).length;\n            c.onMessageReceived = function (msg) {\n              clearTimeout(finishTimeout);\n              msgTracker[msg] = true;\n              self.onMsgReceived(msg);\n              missingMsgs--;\n              if (missingMsgs <= 0 && Object.values(_classPrivateFieldGet2(_msgTracker, self)).every(function (recv) {\n                return recv;\n              })) {\n                \/\/ Last msg received, shortcut out\n                finishFn();\n              } else {\n                \/\/ restart timeout\n                finishTimeout = setTimeout(finishFn, responsesWaitTime);\n              }\n            };\n          }\n        })(1);\n      };\n      c.onMessageReceived = function (msg) {\n        msgTracker[msg] = true;\n        _this.onMsgReceived(msg);\n      };\n    })[\"catch\"](function (e) {\n      return _classPrivateFieldGet2(_onConnectionError, _this).call(_this, e.toString());\n    });\n  }\n  return _createClass(PacketLossEngine, [{\n    key: \"onCredentialsFailure\",\n    set:\n    \/\/ Invoked when unable to fetch TURN server credentials\n    function set(f) {\n      _classPrivateFieldSet2(_onCredentialsFailure, this, f);\n    }\n  }, {\n    key: \"onConnectionError\",\n    set:\n    \/\/ Invoked when unable to establish a connection with TURN server\n    function set(f) {\n      _classPrivateFieldSet2(_onConnectionError, this, f);\n    }\n  }, {\n    key: \"onFinished\",\n    set:\n    \/\/ Invoked when the packet loss measurement is complete\n    function set(f) {\n      _classPrivateFieldSet2(_onFinished, this, f);\n    }\n  }, {\n    key: \"results\",\n    get:\n    \/\/ Invoked when receiving a new message from the TURN server\n\n    function get() {\n      var totalMessages = _classPrivateFieldGet2(_numMsgs, this);\n      var numMessagesSent = Object.keys(_classPrivateFieldGet2(_msgTracker, this)).length;\n      var lostMessages = Object.entries(_classPrivateFieldGet2(_msgTracker, this)).filter(function (_ref4) {\n        var _ref5 = _slicedToArray(_ref4, 2),\n          recv = _ref5[1];\n        return !recv;\n      }).map(function (_ref6) {\n        var _ref7 = _slicedToArray(_ref6, 1),\n          n = _ref7[0];\n        return +n;\n      });\n      var packetLoss = lostMessages.length \/ numMessagesSent;\n      return {\n        totalMessages: totalMessages,\n        numMessagesSent: numMessagesSent,\n        packetLoss: packetLoss,\n        lostMessages: lostMessages\n      };\n    }\n  }]);\n}();\n\nvar _excluded$2 = [\"downloadChunkSize\", \"uploadChunkSize\", \"downloadApiUrl\", \"uploadApiUrl\"];\nvar _loadEngine = \/*#__PURE__*\/new WeakMap();\nvar PacketLossUnderLoadEngine = \/*#__PURE__*\/function (_PacketLossEngine) {\n  function PacketLossUnderLoadEngine() {\n    var _this;\n    var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n      downloadChunkSize = _ref.downloadChunkSize,\n      uploadChunkSize = _ref.uploadChunkSize,\n      downloadApiUrl = _ref.downloadApiUrl,\n      uploadApiUrl = _ref.uploadApiUrl,\n      ptProps = _objectWithoutProperties(_ref, _excluded$2);\n    _classCallCheck(this, PacketLossUnderLoadEngine);\n    _this = _callSuper(this, PacketLossUnderLoadEngine, [ptProps]);\n    \/\/ Internal state\n    _classPrivateFieldInitSpec(_this, _loadEngine, void 0);\n    if (downloadChunkSize || uploadChunkSize) {\n      _classPrivateFieldSet2(_loadEngine, _this, new LoadNetworkEngine({\n        download: downloadChunkSize ? {\n          apiUrl: downloadApiUrl,\n          chunkSize: downloadChunkSize\n        } : null,\n        upload: uploadChunkSize ? {\n          apiUrl: uploadApiUrl,\n          chunkSize: uploadChunkSize\n        } : null\n      }));\n      _superPropSet((PacketLossUnderLoadEngine), \"onCredentialsFailure\", _superPropSet((PacketLossUnderLoadEngine), \"onConnectionError\", _superPropSet((PacketLossUnderLoadEngine), \"onFinished\", function () {\n        return _classPrivateFieldGet2(_loadEngine, _this).stop();\n      }, _this, 1, 1), _this, 1, 1), _this, 1);\n    }\n    return _this;\n  }\n\n  \/\/ Overridden attributes\n  _inherits(PacketLossUnderLoadEngine, _PacketLossEngine);\n  return _createClass(PacketLossUnderLoadEngine, [{\n    key: \"qsParams\",\n    set: function set(qsParams) {\n      _classPrivateFieldGet2(_loadEngine, this) && (_classPrivateFieldGet2(_loadEngine, this).qsParams = qsParams);\n    }\n  }, {\n    key: \"fetchOptions\",\n    set: function set(fetchOptions) {\n      _classPrivateFieldGet2(_loadEngine, this) && (_classPrivateFieldGet2(_loadEngine, this).fetchOptions = fetchOptions);\n    }\n  }, {\n    key: \"onCredentialsFailure\",\n    set: function set(onCredentialsFailure) {\n      var _this2 = this;\n      _superPropSet(PacketLossUnderLoadEngine, \"onCredentialsFailure\", function () {\n        onCredentialsFailure.apply(void 0, arguments);\n        _classPrivateFieldGet2(_loadEngine, _this2) && _classPrivateFieldGet2(_loadEngine, _this2).stop();\n      }, this, 1);\n    }\n  }, {\n    key: \"onConnectionError\",\n    set: function set(onConnectionError) {\n      var _this3 = this;\n      _superPropSet(PacketLossUnderLoadEngine, \"onConnectionError\", function () {\n        onConnectionError.apply(void 0, arguments);\n        _classPrivateFieldGet2(_loadEngine, _this3) && _classPrivateFieldGet2(_loadEngine, _this3).stop();\n      }, this, 1);\n    }\n  }, {\n    key: \"onFinished\",\n    set: function set(onFinished) {\n      var _this4 = this;\n      _superPropSet(PacketLossUnderLoadEngine, \"onFinished\", function () {\n        onFinished.apply(void 0, arguments);\n        _classPrivateFieldGet2(_loadEngine, _this4) && _classPrivateFieldGet2(_loadEngine, _this4).stop();\n      }, this, 1);\n    }\n  }]);\n}(PacketLossEngine);\n\nvar _excluded$1 = [\"reachable\"];\nvar ReachabilityEngine = \/*#__PURE__*\/_createClass(function ReachabilityEngine(targetUrl) {\n  var _this = this;\n  var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},\n    _ref$timeout = _ref.timeout,\n    timeout = _ref$timeout === void 0 ? -1 : _ref$timeout,\n    _ref$fetchOptions = _ref.fetchOptions,\n    fetchOptions = _ref$fetchOptions === void 0 ? {} : _ref$fetchOptions;\n  _classCallCheck(this, ReachabilityEngine);\n  \/\/ Public attributes\n  _defineProperty(this, \"onFinished\", function () {});\n  var finished = false;\n  var finish = function finish(_ref2) {\n    var reachable = _ref2.reachable,\n      rest = _objectWithoutProperties(_ref2, _excluded$1);\n    if (finished) return;\n    finished = true;\n    _this.onFinished(_objectSpread2({\n      targetUrl: targetUrl,\n      reachable: reachable\n    }, rest));\n  };\n  fetch(targetUrl, fetchOptions).then(function (response) {\n    finish({\n      reachable: true,\n      response: response\n    });\n  })[\"catch\"](function (error) {\n    finish({\n      reachable: false,\n      error: error\n    });\n  });\n  timeout > 0 && setTimeout(function () {\n    return finish({\n      reachable: false,\n      error: 'Request timeout'\n    });\n  }, timeout);\n});\n\nvar sum = function sum(vals) {\n  return vals.reduce(function (agg, val) {\n    return agg + val;\n  }, 0);\n};\nvar percentile = function percentile(vals) {\n  var perc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.5;\n  if (!vals.length) return 0;\n  var sortedVals = vals.slice().sort(function (a, b) {\n    return a - b;\n  });\n  var idx = (vals.length - 1) * perc;\n  var rem = idx % 1;\n  if (rem === 0) return sortedVals[Math.round(idx)];\n\n  \/\/ calculate weighted average\n  var edges = [Math.floor, Math.ceil].map(function (rndFn) {\n    return sortedVals[rndFn(idx)];\n  });\n  return edges[0] + (edges[1] - edges[0]) * rem;\n};\n\nvar _config$3 = \/*#__PURE__*\/new WeakMap();\nvar _extractLoadedLatencies = \/*#__PURE__*\/new WeakMap();\nvar MeasurementCalculations = \/*#__PURE__*\/function () {\n  function MeasurementCalculations(config) {\n    var _this = this;\n    _classCallCheck(this, MeasurementCalculations);\n    \/\/ Public methods\n    _defineProperty(this, \"getLatencyPoints\", function (latencyResults) {\n      return latencyResults.timings.map(function (d) {\n        return d.ping;\n      });\n    });\n    _defineProperty(this, \"getLatency\", function (latencyResults) {\n      return percentile(_this.getLatencyPoints(latencyResults), _classPrivateFieldGet2(_config$3, _this).latencyPercentile);\n    });\n    _defineProperty(this, \"getBandwidthPoints\", function (bandwidthResults) {\n      return Object.entries(bandwidthResults).map(function (_ref) {\n        var _ref2 = _slicedToArray(_ref, 2),\n          bytes = _ref2[0],\n          timings = _ref2[1].timings;\n        return timings.map(function (_ref3) {\n          var bps = _ref3.bps,\n            duration = _ref3.duration,\n            ping = _ref3.ping,\n            measTime = _ref3.measTime,\n            serverTime = _ref3.serverTime,\n            transferSize = _ref3.transferSize;\n          return {\n            bytes: +bytes,\n            bps: bps,\n            duration: duration,\n            ping: ping,\n            measTime: measTime,\n            serverTime: serverTime,\n            transferSize: transferSize\n          };\n        });\n      }).flat();\n    });\n    _defineProperty(this, \"getBandwidth\", function (bandwidthResults) {\n      return percentile(_this.getBandwidthPoints(bandwidthResults).filter(function (d) {\n        return d.duration >= _classPrivateFieldGet2(_config$3, _this).bandwidthMinRequestDuration;\n      }).map(function (d) {\n        return d.bps;\n      }).filter(function (bps) {\n        return bps;\n      }), _classPrivateFieldGet2(_config$3, _this).bandwidthPercentile);\n    });\n    _defineProperty(this, \"getLoadedLatency\", function (loadedResults) {\n      return _this.getLatency({\n        timings: _classPrivateFieldGet2(_extractLoadedLatencies, _this).call(_this, loadedResults)\n      });\n    });\n    _defineProperty(this, \"getLoadedJitter\", function (loadedResults) {\n      return _this.getJitter({\n        timings: _classPrivateFieldGet2(_extractLoadedLatencies, _this).call(_this, loadedResults)\n      });\n    });\n    _defineProperty(this, \"getLoadedLatencyPoints\", function (loadedResults) {\n      return _this.getLatencyPoints({\n        timings: _classPrivateFieldGet2(_extractLoadedLatencies, _this).call(_this, loadedResults)\n      });\n    });\n    _defineProperty(this, \"getPacketLoss\", function (plResults) {\n      return plResults.packetLoss;\n    });\n    _defineProperty(this, \"getPacketLossDetails\", function (plResults) {\n      return plResults;\n    });\n    _defineProperty(this, \"getReachability\", function (reachabilityResults) {\n      return !!reachabilityResults.reachable;\n    });\n    _defineProperty(this, \"getReachabilityDetails\", function (d) {\n      return {\n        host: d.host,\n        reachable: d.reachable\n      };\n    });\n    \/\/ Internal state\n    _classPrivateFieldInitSpec(this, _config$3, void 0);\n    \/\/ Internal methods\n    _classPrivateFieldInitSpec(this, _extractLoadedLatencies, function (loadedResults) {\n      return Object.values(loadedResults).filter(\n      \/\/ keep only file sizes that saturated the connection\n      function (d) {\n        return d.timings.length && Math.min.apply(Math, _toConsumableArray(d.timings.map(function (d) {\n          return d.duration;\n        }))) >= _classPrivateFieldGet2(_config$3, _this).loadedRequestMinDuration;\n      }).map(function (d) {\n        return d.sideLatency || [];\n      }).flat().slice(-_classPrivateFieldGet2(_config$3, _this).loadedLatencyMaxPoints);\n    });\n    _classPrivateFieldSet2(_config$3, this, config);\n  }\n  return _createClass(MeasurementCalculations, [{\n    key: \"getJitter\",\n    value: function getJitter(latencyResults) {\n      \/\/ calc jitter as the average latency delta between consecutive samples\n      var pings = this.getLatencyPoints(latencyResults);\n      return pings.length < 2 ? null : pings.reduce(function (_ref4, latency) {\n        var _ref4$sumDeltas = _ref4.sumDeltas,\n          sumDeltas = _ref4$sumDeltas === void 0 ? 0 : _ref4$sumDeltas,\n          prevLatency = _ref4.prevLatency;\n        return {\n          sumDeltas: sumDeltas + (prevLatency !== undefined ? Math.abs(prevLatency - latency) : 0),\n          prevLatency: latency\n        };\n      }, {}).sumDeltas \/ (pings.length - 1);\n    }\n\n    \/\/ last measurements are most accurate\n  }]);\n}();\n\nvar classificationNames = ['bad', 'poor', 'average', 'good', 'great'];\nvar customResultTypes = {\n  loadedLatencyIncrease: function loadedLatencyIncrease(measurements) {\n    return measurements.latency && (measurements.downLoadedLatency || measurements.upLoadedLatency) ? Math.max(measurements.downLoadedLatency, measurements.upLoadedLatency) - measurements.latency : undefined;\n  }\n};\nvar defaultPoints = {\n  packetLoss: 0\n};\nvar _config$2 = \/*#__PURE__*\/new WeakMap();\nvar ScoresCalculations = \/*#__PURE__*\/function () {\n  function ScoresCalculations(config) {\n    _classCallCheck(this, ScoresCalculations);\n    \/\/ Internal state\n    _classPrivateFieldInitSpec(this, _config$2, void 0);\n    _classPrivateFieldSet2(_config$2, this, config);\n  }\n  return _createClass(ScoresCalculations, [{\n    key: \"getScores\",\n    value: function getScores(measurements) {\n      var scores = Object.assign.apply(Object, _toConsumableArray(Object.entries(_classPrivateFieldGet2(_config$2, this).aimMeasurementScoring).map(function (_ref) {\n        var _ref2 = _slicedToArray(_ref, 2),\n          type = _ref2[0],\n          fn = _ref2[1];\n        var val = customResultTypes.hasOwnProperty(type) ? customResultTypes[type](measurements) : measurements[type];\n        return val === undefined ? defaultPoints.hasOwnProperty(type) ? _defineProperty({}, type, defaultPoints[type]) : {} : _defineProperty({}, type, val === undefined ? 0 : +fn(val));\n      })));\n      return Object.assign.apply(Object, [{}].concat(_toConsumableArray(Object.entries(_classPrivateFieldGet2(_config$2, this).aimExperiencesDefs).filter(function (_ref5) {\n        var _ref6 = _slicedToArray(_ref5, 2),\n          input = _ref6[1].input;\n        return input.every(function (k) {\n          return scores.hasOwnProperty(k);\n        });\n      }).map(function (_ref7) {\n        var _ref8 = _slicedToArray(_ref7, 2),\n          k = _ref8[0],\n          _ref8$ = _ref8[1],\n          input = _ref8$.input,\n          pointThresholds = _ref8$.pointThresholds;\n        var sumPoints = Math.max(0, sum(input.map(function (k) {\n          return scores[k];\n        })));\n        var classificationIdx = scaleThreshold(pointThresholds, [0, 1, 2, 3, 4])(sumPoints);\n        var classificationName = classificationNames[classificationIdx];\n        return _defineProperty({}, k, {\n          points: sumPoints,\n          classificationIdx: classificationIdx,\n          classificationName: classificationName\n        });\n      }))));\n    }\n  }]);\n}();\n\nvar _config$1 = \/*#__PURE__*\/new WeakMap();\nvar _measCalc = \/*#__PURE__*\/new WeakMap();\nvar _scoresCalc = \/*#__PURE__*\/new WeakMap();\nvar _calcGetter = \/*#__PURE__*\/new WeakMap();\nvar _getV4Reachability = \/*#__PURE__*\/new WeakMap();\nvar _getV4ReachabilityDetails = \/*#__PURE__*\/new WeakMap();\nvar _getV6Reachability = \/*#__PURE__*\/new WeakMap();\nvar _getV6ReachabilityDetails = \/*#__PURE__*\/new WeakMap();\nvar Results = \/*#__PURE__*\/function () {\n  function Results(config) {\n    var _this = this;\n    _classCallCheck(this, Results);\n    \/\/ Public attributes\n    _defineProperty(this, \"raw\", void 0);\n    _defineProperty(this, \"getUnloadedLatency\", function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getLatency', 'latency');\n    });\n    _defineProperty(this, \"getUnloadedJitter\", function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getJitter', 'latency');\n    });\n    _defineProperty(this, \"getUnloadedLatencyPoints\", function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getLatencyPoints', 'latency', []);\n    });\n    _defineProperty(this, \"getDownLoadedLatency\", function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getLoadedLatency', 'download');\n    });\n    _defineProperty(this, \"getDownLoadedJitter\", function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getLoadedJitter', 'download');\n    });\n    _defineProperty(this, \"getDownLoadedLatencyPoints\", function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getLoadedLatencyPoints', 'download', []);\n    });\n    _defineProperty(this, \"getUpLoadedLatency\", function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getLoadedLatency', 'upload');\n    });\n    _defineProperty(this, \"getUpLoadedJitter\", function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getLoadedJitter', 'upload');\n    });\n    _defineProperty(this, \"getUpLoadedLatencyPoints\", function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getLoadedLatencyPoints', 'upload', []);\n    });\n    _defineProperty(this, \"getDownloadBandwidth\", function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getBandwidth', 'download');\n    });\n    _defineProperty(this, \"getDownloadBandwidthPoints\", function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getBandwidthPoints', 'download', []);\n    });\n    _defineProperty(this, \"getUploadBandwidth\", function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getBandwidth', 'upload');\n    });\n    _defineProperty(this, \"getUploadBandwidthPoints\", function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getBandwidthPoints', 'upload', []);\n    });\n    _defineProperty(this, \"getPacketLoss\", function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getPacketLoss', 'packetLoss');\n    });\n    _defineProperty(this, \"getPacketLossDetails\", function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getPacketLossDetails', 'packetLoss', undefined, true);\n    });\n    _defineProperty(this, \"getScores\", function () {\n      return _classPrivateFieldGet2(_scoresCalc, _this).getScores(_this.getSummary());\n    });\n    \/\/ Internal state\n    _classPrivateFieldInitSpec(this, _config$1, void 0);\n    _classPrivateFieldInitSpec(this, _measCalc, void 0);\n    _classPrivateFieldInitSpec(this, _scoresCalc, void 0);\n    \/\/ Internal methods\n    _classPrivateFieldInitSpec(this, _calcGetter, function (calcFn, resKey) {\n      var defaultVal = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;\n      var surfaceError = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n      return !_this.raw.hasOwnProperty(resKey) || !_this.raw[resKey].started ? defaultVal : surfaceError && _this.raw[resKey].error ? {\n        error: _this.raw[resKey].error\n      } : _classPrivateFieldGet2(_measCalc, _this)[calcFn](_this.raw[resKey].results);\n    });\n    _classPrivateFieldInitSpec(this, _getV4Reachability, function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getReachability', 'v4Reachability');\n    });\n    _classPrivateFieldInitSpec(this, _getV4ReachabilityDetails, function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getReachabilityDetails', 'v4Reachability');\n    });\n    _classPrivateFieldInitSpec(this, _getV6Reachability, function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getReachability', 'v6Reachability');\n    });\n    _classPrivateFieldInitSpec(this, _getV6ReachabilityDetails, function () {\n      return _classPrivateFieldGet2(_calcGetter, _this).call(_this, 'getReachabilityDetails', 'v6Reachability');\n    });\n    _classPrivateFieldSet2(_config$1, this, config);\n    this.clear();\n    _classPrivateFieldSet2(_measCalc, this, new MeasurementCalculations(_classPrivateFieldGet2(_config$1, this)));\n    _classPrivateFieldSet2(_scoresCalc, this, new ScoresCalculations(_classPrivateFieldGet2(_config$1, this)));\n  }\n  return _createClass(Results, [{\n    key: \"isFinished\",\n    get: function get() {\n      return Object.values(this.raw).every(function (d) {\n        return d.finished;\n      });\n    }\n\n    \/\/ Public methods\n  }, {\n    key: \"clear\",\n    value: function clear() {\n      this.raw = Object.assign.apply(Object, [{}].concat(_toConsumableArray(_toConsumableArray(new Set(_classPrivateFieldGet2(_config$1, this).measurements.map(function (m) {\n        return m.type;\n      }))).map(function (m) {\n        return _defineProperty({}, m, {\n          started: false,\n          finished: false,\n          results: {}\n        });\n      }))));\n    }\n  }, {\n    key: \"getSummary\",\n    value: function getSummary() {\n      var items = {\n        download: this.getDownloadBandwidth,\n        upload: this.getUploadBandwidth,\n        latency: this.getUnloadedLatency,\n        jitter: this.getUnloadedJitter,\n        downLoadedLatency: this.getDownLoadedLatency,\n        downLoadedJitter: this.getDownLoadedJitter,\n        upLoadedLatency: this.getUpLoadedLatency,\n        upLoadedJitter: this.getUpLoadedJitter,\n        packetLoss: this.getPacketLoss,\n        v4Reachability: _classPrivateFieldGet2(_getV4Reachability, this),\n        v6Reachability: _classPrivateFieldGet2(_getV6Reachability, this)\n      };\n      return Object.assign.apply(Object, _toConsumableArray(Object.entries(items).map(function (_ref2) {\n        var _ref3 = _slicedToArray(_ref2, 2),\n          key = _ref3[0],\n          fn = _ref3[1];\n        var val = fn();\n        return val === undefined ? {} : _defineProperty({}, key, val);\n      })));\n    }\n  }]);\n}();\n\nvar round = function round(num) {\n  var decimals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n  return !num ? num : Math.round(num * Math.pow(10, decimals)) \/ Math.pow(10, decimals);\n};\nvar latencyPointsParser = function latencyPointsParser(durations) {\n  return durations.map(function (d) {\n    return round(d, 2);\n  });\n};\nvar bpsPointsParser = function bpsPointsParser(pnts) {\n  return pnts.map(function (d) {\n    return {\n      bytes: +d.bytes,\n      bps: round(d.bps)\n    };\n  });\n};\nvar packetLossParser = function packetLossParser(d) {\n  return d.error ? undefined : {\n    numMessages: d.numMessagesSent,\n    lossRatio: round(d.packetLoss, 4)\n  };\n};\nvar resultsParsers = {\n  latencyMs: ['getUnloadedLatencyPoints', latencyPointsParser],\n  download: ['getDownloadBandwidthPoints', bpsPointsParser],\n  upload: ['getUploadBandwidthPoints', bpsPointsParser],\n  downLoadedLatencyMs: ['getDownLoadedLatencyPoints', latencyPointsParser],\n  upLoadedLatencyMs: ['getUpLoadedLatencyPoints', latencyPointsParser],\n  packetLoss: ['getPacketLossDetails', packetLossParser]\n  \/\/ v4Reachability: ['getV4ReachabilityDetails'],\n  \/\/ v6Reachability: ['getV6ReachabilityDetails']\n};\nvar scoreParser = function scoreParser(d) {\n  return {\n    points: d.points,\n    classification: d.classificationName\n  };\n};\nvar logAimResults = function logAimResults(results, _ref) {\n  var apiUrl = _ref.apiUrl;\n  var logData = {};\n  Object.entries(resultsParsers).forEach(function (_ref2) {\n    var _ref3 = _slicedToArray(_ref2, 2),\n      logK = _ref3[0],\n      _ref3$ = _slicedToArray(_ref3[1], 2),\n      fn = _ref3$[0],\n      _ref3$$ = _ref3$[1],\n      parser = _ref3$$ === void 0 ? function (d) {\n        return d;\n      } : _ref3$$;\n    var val = results[fn]();\n    val && (logData[logK] = parser(val));\n  });\n  var scores = results.getScores();\n  scores && (logData.scores = Object.assign.apply(Object, [{}].concat(_toConsumableArray(Object.entries(scores).map(function (_ref4) {\n    var _ref5 = _slicedToArray(_ref4, 2),\n      k = _ref5[0],\n      score = _ref5[1];\n    return _defineProperty({}, k, scoreParser(score));\n  })))));\n  fetch(apiUrl, {\n    method: 'POST',\n    body: JSON.stringify(logData)\n  });\n};\n\nvar _excluded = [\"type\"],\n  _excluded2 = [\"numPackets\"],\n  _excluded3 = [\"bytes\"];\nvar DEFAULT_OPTIMAL_DOWNLOAD_SIZE = 1e6;\nvar DEFAULT_OPTIMAL_UPLOAD_SIZE = 1e6;\nvar OPTIMAL_SIZE_RATIO = 0.5; \/\/ of largest size reached in measurement\n\nvar pausableTypes = ['latency', 'latencyUnderLoad', 'download', 'upload'];\nvar genMeasId = function genMeasId() {\n  return \"\".concat(Math.round(Math.random() * 1e16));\n};\nvar _onFinish = \/*#__PURE__*\/new WeakMap();\nvar _onError = \/*#__PURE__*\/new WeakMap();\nvar _config = \/*#__PURE__*\/new WeakMap();\nvar _results = \/*#__PURE__*\/new WeakMap();\nvar _measurementId = \/*#__PURE__*\/new WeakMap();\nvar _curMsmIdx = \/*#__PURE__*\/new WeakMap();\nvar _curEngine = \/*#__PURE__*\/new WeakMap();\nvar _optimalDownloadChunkSize = \/*#__PURE__*\/new WeakMap();\nvar _optimalUploadChunkSize = \/*#__PURE__*\/new WeakMap();\nvar _running = \/*#__PURE__*\/new WeakMap();\nvar _finished = \/*#__PURE__*\/new WeakMap();\nvar _MeasurementEngine_brand = \/*#__PURE__*\/new WeakSet();\nvar MeasurementEngine = \/*#__PURE__*\/function () {\n  function MeasurementEngine() {\n    var userConfig = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n    _classCallCheck(this, MeasurementEngine);\n    \/\/ Internal methods\n    _classPrivateMethodInitSpec(this, _MeasurementEngine_brand);\n    _defineProperty(this, \"onRunningChange\", function () {});\n    _defineProperty(this, \"onResultsChange\", function () {});\n    _classPrivateFieldInitSpec(this, _onFinish, function () {});\n    _classPrivateFieldInitSpec(this, _onError, function () {});\n    \/\/ Internal state\n    _classPrivateFieldInitSpec(this, _config, void 0);\n    _classPrivateFieldInitSpec(this, _results, void 0);\n    _classPrivateFieldInitSpec(this, _measurementId, genMeasId());\n    _classPrivateFieldInitSpec(this, _curMsmIdx, -1);\n    _classPrivateFieldInitSpec(this, _curEngine, void 0);\n    _classPrivateFieldInitSpec(this, _optimalDownloadChunkSize, DEFAULT_OPTIMAL_DOWNLOAD_SIZE);\n    _classPrivateFieldInitSpec(this, _optimalUploadChunkSize, DEFAULT_OPTIMAL_UPLOAD_SIZE);\n    _classPrivateFieldInitSpec(this, _running, false);\n    _classPrivateFieldInitSpec(this, _finished, false);\n    _classPrivateFieldSet2(_config, this, Object.assign({}, defaultConfig, userConfig, internalConfig));\n    _classPrivateFieldSet2(_results, this, new Results(_classPrivateFieldGet2(_config, this)));\n    _classPrivateFieldGet2(_config, this).autoStart && this.play();\n  }\n\n  \/\/ Public attributes\n  return _createClass(MeasurementEngine, [{\n    key: \"results\",\n    get: function get() {\n      \/\/ read access to results\n      return _classPrivateFieldGet2(_results, this);\n    }\n  }, {\n    key: \"isRunning\",\n    get: function get() {\n      return _classPrivateFieldGet2(_running, this);\n    }\n  }, {\n    key: \"isFinished\",\n    get: function get() {\n      return _classPrivateFieldGet2(_finished, this);\n    }\n  }, {\n    key: \"onFinish\",\n    set:\n    \/\/ callback invoked when all the measurements are finished\n    function set(f) {\n      _classPrivateFieldSet2(_onFinish, this, f);\n    }\n  }, {\n    key: \"onError\",\n    set:\n    \/\/ callback invoked if an error occurs during measurement\n    function set(f) {\n      _classPrivateFieldSet2(_onError, this, f);\n    }\n\n    \/\/ Public methods\n  }, {\n    key: \"pause\",\n    value: function pause() {\n      pausableTypes.includes(_assertClassBrand(_MeasurementEngine_brand, this, _curType).call(this)) && _classPrivateFieldGet2(_curEngine, this).pause();\n      _assertClassBrand(_MeasurementEngine_brand, this, _setRunning).call(this, false);\n    }\n  }, {\n    key: \"play\",\n    value: function play() {\n      if (!_classPrivateFieldGet2(_running, this)) {\n        _assertClassBrand(_MeasurementEngine_brand, this, _setRunning).call(this, true);\n        _assertClassBrand(_MeasurementEngine_brand, this, _next).call(this);\n      }\n    }\n  }, {\n    key: \"restart\",\n    value: function restart() {\n      _assertClassBrand(_MeasurementEngine_brand, this, _clear).call(this);\n      this.play();\n    }\n  }]);\n}();\nfunction _setRunning(running) {\n  if (running !== _classPrivateFieldGet2(_running, this)) {\n    _classPrivateFieldSet2(_running, this, running);\n    this.onRunningChange(_classPrivateFieldGet2(_running, this));\n  }\n}\nfunction _setFinished(finished) {\n  var _this3 = this;\n  if (finished !== _classPrivateFieldGet2(_finished, this)) {\n    _classPrivateFieldSet2(_finished, this, finished);\n    finished && setTimeout(function () {\n      return _classPrivateFieldGet2(_onFinish, _this3).call(_this3, _this3.results);\n    });\n  }\n}\nfunction _curType() {\n  return _classPrivateFieldGet2(_curMsmIdx, this) < 0 || _classPrivateFieldGet2(_curMsmIdx, this) >= _classPrivateFieldGet2(_config, this).measurements.length ? null : _classPrivateFieldGet2(_config, this).measurements[_classPrivateFieldGet2(_curMsmIdx, this)].type;\n}\nfunction _curTypeResults() {\n  return _classPrivateFieldGet2(_results, this).raw[_assertClassBrand(_MeasurementEngine_brand, this, _curType).call(this)] || undefined;\n}\nfunction _clear() {\n  _assertClassBrand(_MeasurementEngine_brand, this, _destroyCurEngine).call(this);\n  _classPrivateFieldSet2(_measurementId, this, genMeasId());\n  _classPrivateFieldSet2(_curMsmIdx, this, -1);\n  _classPrivateFieldSet2(_curEngine, this, undefined);\n  _assertClassBrand(_MeasurementEngine_brand, this, _setRunning).call(this, false);\n  _assertClassBrand(_MeasurementEngine_brand, this, _setFinished).call(this, false);\n  _classPrivateFieldGet2(_results, this).clear();\n}\nfunction _destroyCurEngine() {\n  var engine = _classPrivateFieldGet2(_curEngine, this);\n  if (!engine) return;\n  engine.onFinished = engine.onConnectionError = engine.onFail = engine.onMsgReceived = engine.onCredentialsFailure = engine.onMeasurementResult = function () {};\n  pausableTypes.includes(_assertClassBrand(_MeasurementEngine_brand, this, _curType).call(this)) && engine.pause();\n}\nfunction _next() {\n  var _this4 = this;\n  var _this$curMsmIdx;\n  if (pausableTypes.includes(_assertClassBrand(_MeasurementEngine_brand, this, _curType).call(this)) && _assertClassBrand(_MeasurementEngine_brand, this, _curTypeResults).call(this) && _assertClassBrand(_MeasurementEngine_brand, this, _curTypeResults).call(this).started && !_assertClassBrand(_MeasurementEngine_brand, this, _curTypeResults).call(this).finished && !_assertClassBrand(_MeasurementEngine_brand, this, _curTypeResults).call(this).finishedCurrentRound && !_assertClassBrand(_MeasurementEngine_brand, this, _curTypeResults).call(this).error) {\n    _classPrivateFieldGet2(_curEngine, this).play();\n    return;\n  }\n\n  \/\/ advance to next msm\n  _classPrivateFieldSet2(_curMsmIdx, this, (_this$curMsmIdx = _classPrivateFieldGet2(_curMsmIdx, this), _this$curMsmIdx++, _this$curMsmIdx));\n  if (_classPrivateFieldGet2(_curMsmIdx, this) >= _classPrivateFieldGet2(_config, this).measurements.length) {\n    \/\/ done with measurements\n    _assertClassBrand(_MeasurementEngine_brand, this, _setRunning).call(this, false);\n    _assertClassBrand(_MeasurementEngine_brand, this, _setFinished).call(this, true);\n    return;\n  }\n  var _classPrivateFieldGet2$1 = _classPrivateFieldGet2(_config, this).measurements[_classPrivateFieldGet2(_curMsmIdx, this)],\n    type = _classPrivateFieldGet2$1.type,\n    msmConfig = _objectWithoutProperties(_classPrivateFieldGet2$1, _excluded);\n  var msmResults = _assertClassBrand(_MeasurementEngine_brand, this, _curTypeResults).call(this);\n  var _classPrivateFieldGet3 = _classPrivateFieldGet2(_config, this),\n    downloadApiUrl = _classPrivateFieldGet3.downloadApiUrl,\n    uploadApiUrl = _classPrivateFieldGet3.uploadApiUrl,\n    estimatedServerTime = _classPrivateFieldGet3.estimatedServerTime;\n  var engine;\n  switch (type) {\n    case 'v4Reachability':\n    case 'v6Reachability':\n      engine = new ReachabilityEngine(\"https:\/\/\".concat(msmConfig.host), {\n        fetchOptions: {\n          method: 'GET',\n          mode: 'no-cors'\n        }\n      });\n      engine.onFinished = function (result) {\n        msmResults.finished = true;\n        msmResults.results = _objectSpread2({\n          host: msmConfig.host\n        }, result);\n        _this4.onResultsChange({\n          type: type\n        });\n        _assertClassBrand(_MeasurementEngine_brand, _this4, _next).call(_this4);\n      };\n      break;\n    case 'rpki':\n      engine = new ReachabilityEngine(\"https:\/\/\".concat(_classPrivateFieldGet2(_config, this).rpkiInvalidHost), {\n        timeout: 5000\n      });\n      engine.onFinished = function (result) {\n        (result.response ? result.response.json() : Promise.resolve()).then(function (response) {\n          msmResults.finished = true;\n          msmResults.results = _objectSpread2({\n            host: _classPrivateFieldGet2(_config, _this4).rpkiInvalidHost,\n            filteringInvalids: !result.reachable\n          }, response ? {\n            asn: response.asn,\n            name: response.name\n          } : {});\n          _this4.onResultsChange({\n            type: type\n          });\n          _assertClassBrand(_MeasurementEngine_brand, _this4, _next).call(_this4);\n        });\n      };\n      break;\n    case 'nxdomain':\n      engine = new ReachabilityEngine(\"https:\/\/\".concat(msmConfig.nxhost), {\n        fetchOptions: {\n          mode: 'no-cors'\n        }\n      });\n      engine.onFinished = function (result) {\n        msmResults.finished = true;\n        msmResults.results = {\n          host: msmConfig.nxhost,\n          reachable: result.reachable\n        };\n        _this4.onResultsChange({\n          type: type\n        });\n        _assertClassBrand(_MeasurementEngine_brand, _this4, _next).call(_this4);\n      };\n      break;\n    case 'packetLoss':\n    case 'packetLossUnderLoad':\n      {\n        msmResults.finished = false;\n        var numMsgs = msmConfig.numPackets,\n          ptCfg = _objectWithoutProperties(msmConfig, _excluded2);\n        var _classPrivateFieldGet4 = _classPrivateFieldGet2(_config, this),\n          turnServerUri = _classPrivateFieldGet4.turnServerUri,\n          turnServerCredsApi = _classPrivateFieldGet4.turnServerCredsApiUrl,\n          turnServerUser = _classPrivateFieldGet4.turnServerUser,\n          turnServerPass = _classPrivateFieldGet4.turnServerPass,\n          includeCredentials = _classPrivateFieldGet4.includeCredentials;\n        engine = new PacketLossUnderLoadEngine(_objectSpread2({\n          turnServerUri: turnServerUri,\n          turnServerCredsApi: turnServerCredsApi,\n          turnServerCredsApiIncludeCredentials: includeCredentials,\n          turnServerUser: turnServerUser,\n          turnServerPass: turnServerPass,\n          numMsgs: numMsgs,\n          \/\/ if under load\n          downloadChunkSize: msmConfig.loadDown ? _classPrivateFieldGet2(_optimalDownloadChunkSize, this) : undefined,\n          uploadChunkSize: msmConfig.loadUp ? _classPrivateFieldGet2(_optimalUploadChunkSize, this) : undefined,\n          downloadApiUrl: downloadApiUrl,\n          uploadApiUrl: uploadApiUrl\n        }, ptCfg));\n      }\n      engine.onMsgReceived = function () {\n        msmResults.results = Object.assign({}, engine.results);\n        _this4.onResultsChange({\n          type: type\n        });\n      };\n      engine.onFinished = function () {\n        msmResults.finished = true;\n        _this4.onResultsChange({\n          type: type\n        });\n        _assertClassBrand(_MeasurementEngine_brand, _this4, _next).call(_this4);\n      };\n      engine.onConnectionError = function (e) {\n        msmResults.error = e;\n        _this4.onResultsChange({\n          type: type\n        });\n        _classPrivateFieldGet2(_onError, _this4).call(_this4, \"Connection error while measuring packet loss: \".concat(e));\n        _assertClassBrand(_MeasurementEngine_brand, _this4, _next).call(_this4);\n      };\n      engine.onCredentialsFailure = function () {\n        msmResults.error = 'unable to get turn server credentials';\n        _this4.onResultsChange({\n          type: type\n        });\n        _classPrivateFieldGet2(_onError, _this4).call(_this4, 'Error while measuring packet loss: unable to get turn server credentials.');\n        _assertClassBrand(_MeasurementEngine_brand, _this4, _next).call(_this4);\n      };\n      break;\n    case 'latency':\n    case 'latencyUnderLoad':\n      msmResults.finished = false;\n      engine = new LoggingBandwidthEngine([{\n        dir: 'down',\n        bytes: 0,\n        count: msmConfig.numPackets,\n        bypassMinDuration: true\n      }], {\n        downloadApiUrl: downloadApiUrl,\n        uploadApiUrl: uploadApiUrl,\n        estimatedServerTime: estimatedServerTime,\n        logApiUrl: _classPrivateFieldGet2(_config, this).logMeasurementApiUrl,\n        measurementId: _classPrivateFieldGet2(_measurementId, this),\n        \/\/ if under load\n        downloadChunkSize: msmConfig.loadDown ? _classPrivateFieldGet2(_optimalDownloadChunkSize, this) : undefined,\n        uploadChunkSize: msmConfig.loadUp ? _classPrivateFieldGet2(_optimalUploadChunkSize, this) : undefined\n      });\n      engine.fetchOptions = {\n        credentials: _classPrivateFieldGet2(_config, this).includeCredentials ? 'include' : undefined\n      };\n      engine.onMeasurementResult = engine.onNewMeasurementStarted = function (meas, results) {\n        msmResults.results = Object.assign({}, results.down[0]);\n        _this4.onResultsChange({\n          type: type\n        });\n      };\n      engine.onFinished = function () {\n        msmResults.finished = true;\n        _this4.onResultsChange({\n          type: type\n        });\n        _classPrivateFieldGet2(_running, _this4) && _assertClassBrand(_MeasurementEngine_brand, _this4, _next).call(_this4);\n      };\n      engine.onConnectionError = function (e) {\n        msmResults.error = e;\n        _this4.onResultsChange({\n          type: type\n        });\n        _classPrivateFieldGet2(_onError, _this4).call(_this4, \"Connection error while measuring latency: \".concat(e));\n        _assertClassBrand(_MeasurementEngine_brand, _this4, _next).call(_this4);\n      };\n      engine.play();\n      break;\n    case 'download':\n    case 'upload':\n      if (msmResults.finished || msmResults.error) {\n        _assertClassBrand(_MeasurementEngine_brand, this, _next).call(this); \/\/ skip, already concluded this bandwidth measurement type\n      } else {\n        delete msmResults.finishedCurrentRound;\n        var measureParallelLatency = _classPrivateFieldGet2(_config, this)[\"measure\".concat(type === 'download' ? 'Down' : 'Up', \"loadLoadedLatency\")];\n        engine = new LoggingBandwidthEngine([_objectSpread2({\n          dir: type === 'download' ? 'down' : 'up'\n        }, msmConfig)], {\n          downloadApiUrl: downloadApiUrl,\n          uploadApiUrl: uploadApiUrl,\n          estimatedServerTime: estimatedServerTime,\n          logApiUrl: _classPrivateFieldGet2(_config, this).logMeasurementApiUrl,\n          measurementId: _classPrivateFieldGet2(_measurementId, this),\n          measureParallelLatency: measureParallelLatency,\n          parallelLatencyThrottleMs: _classPrivateFieldGet2(_config, this).loadedLatencyThrottle\n        });\n        engine.fetchOptions = {\n          credentials: _classPrivateFieldGet2(_config, this).includeCredentials ? 'include' : undefined\n        };\n        engine.finishRequestDuration = _classPrivateFieldGet2(_config, this).bandwidthFinishRequestDuration;\n        engine.onNewMeasurementStarted = function (_ref) {\n          var count = _ref.count,\n            bytes = _ref.bytes;\n          var res = msmResults.results = Object.assign({}, msmResults.results);\n          !res.hasOwnProperty(bytes) && (res[bytes] = {\n            timings: [],\n            numMeasurements: 0,\n            sideLatency: measureParallelLatency ? [] : undefined\n          });\n\n          \/\/ check if count hasn't already been added\n          if (res[bytes].numMeasurements - res[bytes].timings.length !== count) {\n            res[bytes].numMeasurements += count;\n            _this4.onResultsChange({\n              type: type\n            });\n          }\n        };\n        engine.onMeasurementResult = function (_ref2) {\n          var bytes = _ref2.bytes,\n            timing = _objectWithoutProperties(_ref2, _excluded3);\n          \/\/ merge in new result\n          msmResults.results[bytes].timings.push(timing);\n          msmResults.results = Object.assign({}, msmResults.results);\n          _this4.onResultsChange({\n            type: type\n          });\n        };\n        engine.onParallelLatencyResult = function (res) {\n          \/\/ merge in new latency result\n          msmResults.results[msmConfig.bytes].sideLatency.push(res);\n          msmResults.results = Object.assign({}, msmResults.results);\n          _this4.onResultsChange({\n            type: type\n          });\n        };\n        engine.onFinished = function (results) {\n          var isLastMsmOfType = !_classPrivateFieldGet2(_config, _this4).measurements.slice(_classPrivateFieldGet2(_curMsmIdx, _this4) + 1).map(function (d) {\n            return d.type;\n          }).includes(type);\n          var minDuration = Math.min.apply(Math, _toConsumableArray(Object.values(type === 'download' ? results.down : results.up).slice(-1)[0].timings.map(function (d) {\n            return d.duration;\n          })));\n          var reachedEndOfMsmType = isLastMsmOfType || !msmConfig.bypassMinDuration && minDuration > _classPrivateFieldGet2(_config, _this4).bandwidthFinishRequestDuration;\n          if (!reachedEndOfMsmType) {\n            msmResults.finishedCurrentRound = true;\n          } else {\n            msmResults.finished = true;\n            _this4.onResultsChange({\n              type: type\n            });\n\n            \/\/ record optimal load size\n            var largestSize = Object.keys(msmResults.results).map(function (n) {\n              return +n;\n            }).sort(function (a, b) {\n              return b - a;\n            })[0];\n            var optimalSize = largestSize * OPTIMAL_SIZE_RATIO;\n            type === 'download' && _classPrivateFieldSet2(_optimalDownloadChunkSize, _this4, optimalSize);\n            type === 'upload' && _classPrivateFieldSet2(_optimalUploadChunkSize, _this4, optimalSize);\n          }\n          _classPrivateFieldGet2(_running, _this4) && _assertClassBrand(_MeasurementEngine_brand, _this4, _next).call(_this4);\n        };\n        engine.onConnectionError = function (e) {\n          msmResults.error = e;\n          _this4.onResultsChange({\n            type: type\n          });\n          _classPrivateFieldGet2(_onError, _this4).call(_this4, \"Connection error while measuring \".concat(type, \": \").concat(e));\n          _assertClassBrand(_MeasurementEngine_brand, _this4, _next).call(_this4);\n        };\n        engine.play();\n      }\n      break;\n  }\n  _classPrivateFieldSet2(_curEngine, this, engine);\n  msmResults.started = true;\n  this.onResultsChange({\n    type: type\n  });\n}\nvar _logAimApiUrl = \/*#__PURE__*\/new WeakMap();\nvar _logFinalResults = \/*#__PURE__*\/new WeakMap();\nvar LoggingMeasurementEngine = \/*#__PURE__*\/function (_MeasurementEngine2) {\n  function LoggingMeasurementEngine(userConfig) {\n    var _this;\n    _classCallCheck(this, LoggingMeasurementEngine);\n    for (var _len = arguments.length, pt = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n      pt[_key - 1] = arguments[_key];\n    }\n    _this = _callSuper(this, LoggingMeasurementEngine, [userConfig].concat(pt));\n    \/\/ Internal state\n    _classPrivateFieldInitSpec(_this, _logAimApiUrl, void 0);\n    \/\/ Internal methods\n    _classPrivateFieldInitSpec(_this, _logFinalResults, function (results) {\n      _classPrivateFieldGet2(_logAimApiUrl, _this) && logAimResults(results, {\n        apiUrl: _classPrivateFieldGet2(_logAimApiUrl, _this)\n      });\n    });\n    _superPropSet((LoggingMeasurementEngine), \"onFinish\", _classPrivateFieldGet2(_logFinalResults, _this), _this, 1);\n    _classPrivateFieldSet2(_logAimApiUrl, _this, Object.assign({}, defaultConfig, userConfig, internalConfig).logAimApiUrl);\n    return _this;\n  }\n\n  \/\/ Public attributes\n  _inherits(LoggingMeasurementEngine, _MeasurementEngine2);\n  return _createClass(LoggingMeasurementEngine, [{\n    key: \"onFinish\",\n    set: function set(onFinish) {\n      var _this2 = this;\n      _superPropSet(LoggingMeasurementEngine, \"onFinish\", function (results) {\n        onFinish(results);\n        _classPrivateFieldGet2(_logFinalResults, _this2).call(_this2, results);\n      }, this, 1);\n    }\n  }]);\n}(MeasurementEngine);\n\nreturn LoggingMeasurementEngine;\n\n}\n\nconst $=id=>root.getElementById(id);\nconst plan=[{type:'latency',numPackets:5},...['download','upload'].flatMap(type=>[{type,bytes:100000,count:5,bypassMinDuration:true},{type,bytes:1000000,count:5},{type,bytes:5000000,count:5},{type,bytes:20000000,count:1}])];\nlet active=null;\nconst phases={latency:'1 \/ 3 PING\uff08HTTP\u5fdc\u7b54\u9045\u5ef6\uff09\u3092\u6e2c\u5b9a\u4e2d',download:'2 \/ 3 \u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3092\u6e2c\u5b9a\u4e2d',upload:'3 \/ 3 \u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3092\u6e2c\u5b9a\u4e2d'};\nfunction format(value,divisor=1){return typeof value==='number'&&Number.isFinite(value)&&value>0?(value\/divisor<0.1?'<0.1':(value\/divisor).toLocaleString('ja-JP',{minimumFractionDigits:1,maximumFractionDigits:1})):'\u2014'}\nfunction formatJitter(value){return typeof value==='number'&&Number.isFinite(value)&&value>=0?value.toLocaleString('ja-JP',{minimumFractionDigits:1,maximumFractionDigits:1}):'\u2014'}\nfunction referenceBucket(value,low,high){return typeof value==='number'&&Number.isFinite(value)&&value>=0?(value<=low?0:value<=high?1:2):-1}\nfunction clearReferenceMarkers(){for(const kind of ['ping','jitter'])for(let i=0;i<3;i++){$('ref-'+kind+'-'+i).dataset.selected='false';$('mark-'+kind+'-'+i).hidden=true;$('mark-'+kind+'-'+i).textContent='';}}\nfunction showReferenceMarkers(ping,jitter){clearReferenceMarkers();for(const [kind,value,low,high] of [['ping',ping,100,200],['jitter',jitter,20,40]]){const bucket=referenceBucket(value,low,high);if(bucket<0)continue;$('ref-'+kind+'-'+bucket).dataset.selected='true';const mark=$('mark-'+kind+'-'+bucket);mark.textContent='\u4eca\u56de\u306e\u7d50\u679c\u306f\u3053\u3053\uff1a'+String(value)+' ms';mark.hidden=false;}}\nfunction updateResults(run){if(active!==run)return;const r=run.engine.results;$('download').textContent=format(r.getDownloadBandwidth(),1e6);$('upload').textContent=format(r.getUploadBandwidth(),1e6);$('latency').textContent=formatJitter(r.getUnloadedLatency());$('jitter').textContent=formatJitter(r.getUnloadedJitter());}\nfunction stop(run,state,message){if(active!==run)return;active=null;if(state==='\u5b8c\u4e86')showReferenceMarkers(run.engine.results.getUnloadedLatency(),run.engine.results.getUnloadedJitter());else clearReferenceMarkers();if(state!=='\u5b8c\u4e86')$('jitter').textContent='\u2014';$('transfer').dataset.mode='idle';$('transfer-label').textContent=state==='\u5b8c\u4e86'?'\u9001\u53d7\u4fe1\u5b8c\u4e86':state==='\u4e2d\u6b62'?'\u9001\u53d7\u4fe1\u3092\u4e2d\u6b62':'\u9001\u53d7\u4fe1\u3092\u505c\u6b62';$('request-info').textContent='\u73fe\u5728\u3001\u6e2c\u5b9a\u7528\u30c7\u30fc\u30bf\u306e\u9001\u53d7\u4fe1\u306f\u884c\u3063\u3066\u3044\u307e\u305b\u3093\u3002';clearInterval(run.clock);clearTimeout(run.deadline);run.engine?.pause();run.controller.abort();$('state').textContent=state;$('phase').textContent=state==='\u5b8c\u4e86'?'\u6e2c\u5b9a\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f':state==='\u4e2d\u6b62'?'\u6e2c\u5b9a\u3092\u4e2d\u6b62\u3057\u307e\u3057\u305f':'\u6e2c\u5b9a\u3092\u5b8c\u4e86\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f';$('status').textContent=message;$('start').disabled=false;$('start').textContent='\u3082\u3046\u4e00\u5ea6\u6e2c\u5b9a\u3059\u308b';$('cancel').hidden=true;root.querySelector('.dial span').textContent=state==='\u5b8c\u4e86'?'TEST COMPLETE':'READY TO CHECK';}\n$('start').addEventListener('click',()=>{\n if(active)return;\n clearReferenceMarkers();\n const run={controller:new AbortController(),bytes:0,started:Date.now(),engine:null};active=run;\n ['download','upload','latency','jitter'].forEach(id=>$(id).textContent='\u2014');$('progress').value=0;$('start').disabled=true;$('cancel').hidden=false;$('state').textContent='\u6e2c\u5b9a\u4e2d';$('status').textContent='\u6e2c\u5b9a\u4e2d\u306e\u6570\u5024\u306f\u66ab\u5b9a\u5024\u3067\u3059\u3002\u4e2d\u6b62\u3059\u308b\u3068\u9001\u53d7\u4fe1\u3092\u505c\u6b62\u3057\u307e\u3059\u3002';$('elapsed').textContent='0 \u79d2';root.querySelector('.dial span').textContent='MEASURING';\n const fail=message=>stop(run,'\u30a8\u30e9\u30fc',message);\n const scopedFetch=async(url,options={})=>{\n  if(active!==run)throw new DOMException('Aborted','AbortError');\n  const parsed=new URL(url);if(parsed.origin!=='https:\/\/speed.cloudflare.com'||!['\/__down','\/__up'].includes(parsed.pathname)){fail('\u6e2c\u5b9a\u5148\u304c\u60f3\u5b9a\u3068\u7570\u306a\u308b\u305f\u3081\u3001\u5b89\u5168\u306e\u305f\u3081\u505c\u6b62\u3057\u307e\u3057\u305f\u3002');throw new Error('Unexpected endpoint');}\n  const bytes=parsed.pathname==='\/__down'?Number(parsed.searchParams.get('bytes')||0):new Blob([options.body||'']).size;\n  if(!Number.isFinite(bytes)||bytes<0||run.bytes+bytes>104000000){fail('\u30c7\u30fc\u30bf\u91cf\u306e\u4e0a\u9650\u306b\u9054\u3057\u305f\u305f\u3081\u505c\u6b62\u3057\u307e\u3057\u305f\u3002\u8868\u793a\u6e08\u307f\u306e\u6570\u5024\u306f\u9014\u4e2d\u7d50\u679c\u3067\u3059\u3002');throw new Error('Payload budget exceeded');}run.bytes+=bytes;\n  const direction=parsed.pathname==='\/__up'?'upload':bytes===0?'latency':'download';\n  const labels={download:'\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\uff1aCloudflare \u2192 \u7aef\u672b',upload:'\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\uff1a\u7aef\u672b \u2192 Cloudflare',latency:'PING\uff1a\u7aef\u672b \u21c4 Cloudflare'};\n  $('transfer').dataset.mode=direction;if($('transfer-label').textContent!==labels[direction])$('transfer-label').textContent=labels[direction];\n  $('request-info').textContent=direction==='latency'?'\u73fe\u5728\u306e\u8981\u6c42\uff1aPING \u6e2c\u5b9a \/ \u672c\u6587 0 \u30d0\u30a4\u30c8\uff08\u901a\u4fe1\u30d8\u30c3\u30c0\u30fc\u7b49\u306f\u5225\u9014\uff09':'\u73fe\u5728\u306e\u8981\u6c42\uff1a'+bytes.toLocaleString('ja-JP')+' \u30d0\u30a4\u30c8\uff08'+(bytes\/1000000)+' MB\uff09'+(direction==='download'?'\u3092\u53d7\u4fe1':'\u3092\u9001\u4fe1');\n  try{const response=await fetch(url,{...options,signal:run.controller.signal,credentials:'omit',cache:'no-store',referrerPolicy:'no-referrer'});if(!response.ok)throw new Error('HTTP '+response.status);return response;}catch(error){if(active===run)fail('\u6e2c\u5b9a\u5148\u306b\u63a5\u7d9a\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u901a\u4fe1\u74b0\u5883\u30fbVPN\u30fb\u5e83\u544a\u30d6\u30ed\u30c3\u30af\u8a2d\u5b9a\u3092\u78ba\u8a8d\u3057\u3066\u3001\u3082\u3046\u4e00\u5ea6\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002\u9014\u4e2d\u7d50\u679c\u306f\u53c2\u8003\u5024\u3067\u3059\u3002');throw error;}\n };\n try{\n const Engine=createSpeedEngine(scopedFetch);run.engine=new Engine({autoStart:false,measurements:plan,includeCredentials:false,logAimApiUrl:null,logMeasurementApiUrl:null,measureDownloadLoadedLatency:false,measureUploadLoadedLatency:false,estimatedServerTime:0});\n run.engine.onResultsChange=({type})=>{if(active!==run)return;$('phase').textContent=phases[type]||'\u6e2c\u5b9a\u4e2d';$('progress').value={latency:0,download:1,upload:2}[type]||0;updateResults(run);};\n run.engine.onError=()=>fail('\u6e2c\u5b9a\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u63a5\u7d9a\u3092\u78ba\u8a8d\u3057\u3066\u518d\u6e2c\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u8868\u793a\u6e08\u307f\u306e\u6570\u5024\u306f\u9014\u4e2d\u7d50\u679c\u3067\u3059\u3002');\n run.engine.onFinish=()=>{if(active!==run)return;updateResults(run);$('progress').value=3;const missing=['download','upload','latency','jitter'].some(id=>$(id).textContent==='\u2014');stop(run,'\u5b8c\u4e86',missing?'\u4e00\u90e8\u306e\u5024\u306f\u6709\u52b9\u306a\u6e2c\u5b9a\u30c7\u30fc\u30bf\u304c\u8db3\u308a\u305a\u7b97\u51fa\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u300c\u2014\u300d\u306f 0 \u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u9ad8\u901f\u56de\u7dda\u3084\u30d6\u30e9\u30a6\u30b6\u30fc\u306e\u5236\u9650\u304c\u5f71\u97ff\u3059\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002':'\u6e2c\u5b9a\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f\u3002Cloudflare \u307e\u3067\u306e\u4eca\u56de\u306e\u53c2\u8003\u5024\u3067\u3059\u3002\u6642\u9593\u5e2f\u3084 Wi-Fi \u306e\u6761\u4ef6\u3092\u305d\u308d\u3048\u3066\u6bd4\u8f03\u3057\u3066\u304f\u3060\u3055\u3044\u3002');};\n run.clock=setInterval(()=>{if(active===run)$('elapsed').textContent=Math.floor((Date.now()-run.started)\/1000)+' \u79d2';},1000);\n run.deadline=setTimeout(()=>fail('90 \u79d2\u3067\u6e2c\u5b9a\u3092\u7d42\u4e86\u3057\u307e\u3057\u305f\u3002\u56de\u7dda\u304c\u9045\u3044\u3001\u307e\u305f\u306f\u6e2c\u5b9a\u901a\u4fe1\u304c\u5236\u9650\u3055\u308c\u3066\u3044\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002\u8868\u793a\u6e08\u307f\u306e\u6570\u5024\u306f\u9014\u4e2d\u7d50\u679c\u3067\u3059\u3002'),90000);\n run.engine.play();\n }catch(error){fail('\u3053\u306e\u30d6\u30e9\u30a6\u30b6\u30fc\u3067\u6e2c\u5b9a\u3092\u958b\u59cb\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u6700\u65b0\u7248\u306e\u30d6\u30e9\u30a6\u30b6\u30fc\u3067\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002');}\n});\n$('cancel').addEventListener('click',()=>{if(active)stop(active,'\u4e2d\u6b62','\u6e2c\u5b9a\u3092\u4e2d\u6b62\u3057\u3001\u9001\u53d7\u4fe1\u3092\u505c\u6b62\u3057\u307e\u3057\u305f\u3002\u8868\u793a\u6e08\u307f\u306e\u6570\u5024\u306f\u9014\u4e2d\u7d50\u679c\u3067\u3059\u3002\u3082\u3046\u4e00\u5ea6\u6e2c\u5b9a\u3067\u304d\u307e\u3059\u3002');});\nwindow.addEventListener('pagehide',()=>{if(active)stop(active,'\u4e2d\u6b62','\u30da\u30fc\u30b8\u3092\u96e2\u308c\u305f\u305f\u3081\u6e2c\u5b9a\u3092\u4e2d\u6b62\u3057\u307e\u3057\u305f\u3002');});\n\n})();\n\n\/\/ -->\n<\/script>\n\n\n\n\n<style>\/* Page-scoped title fit and below-tool navigation *\/body.page-id-15 #bfl-below-tool-nav{max-width:1100px!important;box-sizing:border-box;margin:40px auto 0;padding:24px 0;border-top:1px solid #dce5e8}body.page-id-15 #bfl-below-tool-nav>nav{justify-content:center}<\/style>\n<div id=\"bfl-below-tool-nav\"><\/div>\n<script>\n<!--\n(function(){var nav=document.querySelector(\"body.page-id-15 > .wp-site-blocks > header nav.wp-block-navigation\"),slot=document.getElementById(\"bfl-below-tool-nav\");if(nav&&slot)slot.appendChild(nav);})();\n\/\/ -->\n<\/script>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-15","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/tools.bl-forest.com\/index.php?rest_route=\/wp\/v2\/pages\/15","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tools.bl-forest.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/tools.bl-forest.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/tools.bl-forest.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tools.bl-forest.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=15"}],"version-history":[{"count":5,"href":"https:\/\/tools.bl-forest.com\/index.php?rest_route=\/wp\/v2\/pages\/15\/revisions"}],"predecessor-version":[{"id":106,"href":"https:\/\/tools.bl-forest.com\/index.php?rest_route=\/wp\/v2\/pages\/15\/revisions\/106"}],"wp:attachment":[{"href":"https:\/\/tools.bl-forest.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=15"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}