PageSourceSearch

https://myssl.com/scripts/main.js?v=v2.0.156

js myssl.com collected 2026-10-01 11:37:59 UTC 90,385 bytes, 1,133 lines download raw bytes

1/* eslint-disable require-jsdoc */
2/* eslint-disable no-var */
3/* eslint-disable space-before-function-paren */
4/* eslint-disable quotes */
5/* eslint-disable one-var */
6/* eslint-disable camelcase */
7/* eslint-disable guard-for-in */
8/* !
9 *
10 *  myssl.com
11 *  Copyright 2015 Google Inc. All rights reserved.
12 *
13 *  Licensed under the Apache License, Version 2.0 (the "License");
14 *  you may not use this file except in compliance with the License.
15 *  You may obtain a copy of the License at
16 *
17 *    https://www.apache.org/licenses/LICENSE-2.0
18 *
19 *  Unless required by applicable law or agreed to in writing, software
20 *  distributed under the License is distributed on an "AS IS" BASIS,
21 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 *  See the License for the specific language governing permissions and
23 *  limitations under the License
24 *
25 */
26/* eslint-env browser */
27
28(function (window) {
29  "use strict";
30  /* \
31  |*|
32  |*|  :: MiniDaemon ::
33  |*|
34  |*|  Revision #2 - September 26, 2014
35  |*|
36  |*|  https://developer.mozilla.org/en-US/docs/Web/API/window.setInterval
37  |*|  https://developer.mozilla.org/User:fusionchess
38  |*|  https://github.com/madmurphy/minidaemon.js
39  |*|
40  |*|  This framework is released under the GNU Lesser General Public License, version 3 or later.
41  |*|  http://www.gnu.org/licenses/lgpl-3.0.html
42  |*|
43  \*/
44
45  function MiniDaemon(oOwner, fTask, nRate, nLen) {
46    if (!(this && this instanceof MiniDaemon)) {
47      return;
48    }
49    if (arguments.length < 2) {
50      throw new TypeError("MiniDaemon - not enough arguments");
51    }
52    if (oOwner) {
53      this.owner = oOwner;
54    }
55    this.task = fTask;
56    if (isFinite(nRate) && nRate > 0) {
57      this.rate = Math.floor(nRate);
58    }
59    if (nLen > 0) {
60      this.length = Math.floor(nLen);
61    }
62  }
63
64  MiniDaemon.prototype.owner = null;
65  MiniDaemon.prototype.task = null;
66  MiniDaemon.prototype.rate = 100;
67  MiniDaemon.prototype.length = Infinity;
68
69  /* These properties should be read-only */
70
71  MiniDaemon.prototype.SESSION = -1;
72  MiniDaemon.prototype.INDEX = 0;
73  MiniDaemon.prototype.PAUSED = true;
74  MiniDaemon.prototype.BACKW = true;
75
76  /* Global methods */
77
78  MiniDaemon.forceCall = function (oDmn) {
79    oDmn.INDEX += oDmn.BACKW ? -1 : 1;
80    if (
81      oDmn.task.call(oDmn.owner, oDmn.INDEX, oDmn.length, oDmn.BACKW) ===
82        false ||
83      oDmn.isAtEnd()
84    ) {
85      oDmn.pause();
86      return false;
87    }
88    return true;
89  };
90
91  /* Instances methods */
92
93  MiniDaemon.prototype.isAtEnd = function () {
94    return this.BACKW
95      ? isFinite(this.length) && this.INDEX < 1
96      : this.INDEX + 1 > this.length;
97  };
98
99  MiniDaemon.prototype.synchronize = function () {
100    if (this.PAUSED) {
101      return;
102    }
103    clearInterval(this.SESSION);
104    this.SESSION = setInterval(MiniDaemon.forceCall, this.rate, this);
105  };
106
107  MiniDaemon.prototype.pause = function () {
108    clearInterval(this.SESSION);
109    this.PAUSED = true;
110  };
111
112  MiniDaemon.prototype.start = function (bReverse) {
113    var bBackw = Boolean(bReverse);
114    if (this.BACKW === bBackw && (this.isAtEnd() || !this.PAUSED)) {
115      return;
116    }
117    this.BACKW = bBackw;
118    this.PAUSED = false;
119    this.synchronize();
120  };
121
122  if (window.MiniDaemon === undefined) {
123    window.MiniDaemon = MiniDaemon;
124  }
125
126  // 增加参数验证和过滤
127
128  var paramsFilter = {
129    // "domain": /^([\S]+[\S]*\.[\S]{2,4})|((?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4})$/ig,
130    ip: /^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$/gi,
131    f: /^\d*$/gi,
132    port: /^\d{1,5}$/gi,
133    ext: /^\d*$/gi,
134    hide: /^\d*$/gi,
135  };
136
137  // var getParamsAsObject = function (query) {
138  //   query = query.substring(query.indexOf("?") + 1);
139  //   var re = /([^&=]+)=?([^&]*)/g;
140  //   var decodeRE = /\+/g;
141  //   var decode = function (str) {
142  //     return decodeURIComponent(str.replace(decodeRE, " "));
143  //   };
144  //   var params = {},
145  //     e;
146  //   while ((e = re.exec(query))) {
147  //     var k = decode(e[1]);
148  //     var v = decode(e[2]) || "";
149  //     // 这里做参数校验
150  //     var temp_validation = paramsFilter[k];
151  //     var temp_re = v.match(temp_validation) || "";
152  //     if (temp_re.length && temp_re[0]) {
153  //       v = temp_re[0];
154  //     }
155  //     if (k.substring(k.length - 2) === "[]") {
156  //       k = k.substring(0, k.length - 2);
157  //       (params[k] || (params[k] = [])).push(v);
158  //     } else {
159  //       params[k] = v;
160  //     }
161  //   }
162
163  //   // 下面两段代码会引起 xss漏洞,慎用
164  //   var assign = function (obj, keyPath, value) {
165  //     var lastKeyIndex = keyPath.length - 1;
166  //     for (var i = 0; i < lastKeyIndex; ++i) {
167  //       var key = keyPath[i];
168  //       if (!(key in obj)) obj[key] = {};
169  //       obj = obj[key];
170  //     }
171  //     obj[keyPath[lastKeyIndex]] = value;
172  //   };
173
174  //   for (var prop in params) {
175  //     var structure = prop.split("[");
176  //     if (structure.length > 1) {
177  //       var levels = [];
178  //       structure.forEach(function (item, i) {
179  //         var key = item.replace(/[?[\]\\ ]/g, "");
180  //         levels.push(key);
181  //       });
182  //       assign(params, levels, params[prop]);
183  //       delete params[prop];
184  //     }
185  //   }
186  //   console.log(params);
187  //   return params;
188  // };
189
190  var newGetParamsAsObject = function (query) {
191    query = query.substring(query.indexOf("?") + 1);
192
193    var re = /([^&=]+)=?([^&]*)/g;
194    var decodeRE = /\+/g;
195
196    var decode = function (str) {
197      return decodeURIComponent(str.replace(decodeRE, " "));
198    };
199
200    var params = {},
201      e;
202    while ((e = re.exec(query))) {
203      var k = decode(e[1]);
204      var v = decode(e[2]) || "";
205      // 这里做参数校验
206      var temp_validation = paramsFilter[k];
207      var temp_re = v.match(temp_validation) || "";
208      if (temp_re.length && temp_re[0]) {
209        v = temp_re[0];
210      }
211      if (k.substring(k.length - 2) !== "[]") {
212        params[k] = v;
213      }
214    }
215
216    return params;
217  };
218
219  window.queryParams = newGetParamsAsObject(location.search);
220  // // Check to make sure service workers are supported in the current browser,
221  // // and that the current page is accessed from a secure origin. Using a
222  // // service worker from an insecure origin will trigger JS console errors. See
223  // // http://www.chromium.org/Home/chromium-security/prefer-secure-origins-for-powerful-new-features
224  // var isLocalhost = Boolean(window.location.hostname === 'localhost' ||
225  //     // [::1] is the IPv6 localhost address.
226  //     window.location.hostname === '[::1]' ||
227  //     // 127.0.0.1/8 is considered localhost for IPv4.
228  //     window.location.hostname.match(
229  //       /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
230  //     )
231  //   );
232  //
233  // if ('serviceWorker' in navigator &&
234  //     (window.location.protocol === 'https:' || isLocalhost)) {
235  //   navigator.serviceWorker.register('service-worker.js')
236  //   .then(function(registration) {
237  //     // updatefound is fired if service-worker.js changes.
238  //     registration.onupdatefound = function() {
239  //       // updatefound is also fired the very first time the SW is installed,
240  //       // and there's no need to prompt for a reload at that point.
241  //       // So check here to see if the page is already controlled,
242  //       // i.e. whether there's an existing service worker.
243  //       if (navigator.serviceWorker.controller) {
244  //         // The updatefound event implies that registration.installing is set:
245  //         // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-container-updatefound-event
246  //         var installingWorker = registration.installing;
247  //
248  //         installingWorker.onstatechange = function() {
249  //           switch (installingWorker.state) {
250  //             case 'installed':
251  //               // At this point, the old content will have been purged and the
252  //               // fresh content will have been added to the cache.
253  //               // It's the perfect time to display a "New content is
254  //               // available; please refresh." message in the page's interface.
255  //               break;
256  //
257  //             case 'redundant':
258  //               throw new Error('The installing ' +
259  //                               'service worker became redundant.');
260  //
261  //             default:
262  //               // Ignore
263  //           }
264  //         };
265  //       }
266  //     };
267  //   }).catch(function(e) {
268  //     console.error('Error during service worker registration:', e);
269  //   });
270  // }
271
272  // Your custom JavaScript goes here
273
274  var taLock = {
275    __count__: 0,
276    __unlocked__: true,
277    lock: function () {
278      this.__count__ += 1;
279      this.__unlocked__ = false;
280    },
281    free: function () {
282      if (this.__count__ > 0) {
283        this.__count__ -= 1;
284      }
285      this.__unlocked__ = true;
286    },
287    is_locked: function () {
288      return !this.__unlocked__;
289    },
290    new: function () {
291      this.__count__ += 0;
292      this.__unlocked__ = true;
293      return this;
294    },
295  };
296  if (window.taLock === undefined) {
297    window.taLock = taLock;
298  }
299
300  $.fn.extend({
301    animateCss: function (animationName) {
302      var animationEnd =
303        "webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend";
304      this.addClass("animated " + animationName).one(animationEnd, function () {
305        $(this).removeClass("animated " + animationName);
306      });
307    },
308  });
309  window._GLOBAL_DATE_FMT = "YYYY-MM-DD HH:mm:ss";
310
311  function errResp(status, dom) {
312    if (status == 429) {
313      $(dom).removeClass("hidden").text("请求过快,请稍后再试");
314    } else if (status >= 500) {
315      $(dom).removeClass("hidden").text("内部错误");
316    } else if (status != 429 && err >= 400) {
317      $(dom).removeClass("hidden").text("40x");
318    }
319  }
320
321  window.errResp = errResp;
322
323  function getSupportFileStatus() {
324    if (typeof FileReader == "undefined") {
325      return true;
326    } else {
327      return false;
328    }
329  }
330
331  window.getSupportFileStatus = getSupportFileStatus;
332
333  function unsupportFile(errordom) {
334    $(errordom)
335      .removeClass("hidden")
336      .text("您的浏览器版本不支持文件上传功能,请升级您的浏览器!");
337  }
338
339  window.unsupportFile = unsupportFile;
340
341  var common_reg = {
342    ipv: function (option) {
343      return /^(\s*)?(http:\/\/|https:\/\/)?(\d+\.\d+\.\d+\.\d)(\:\d{1,5})?/.test(
344        option
345      );
346    },
347    domain: function (option) {
348      return /^(\s*)?(http:\/\/|https:\/\/)?[\S]+[\S]*\.[\S]{2,4}/g.test(
349        option
350      );
351    },
352    domain_only: function (option) {
353      return /^(\s*)?(http:\/\/|https:\/\/)?[0-9a-zA-Z_]+[0-9a-zA-Z\.-]*\.[a-zA-Z]{2,4}/g.test(
354        option
355      );
356    },
357    result: function (option) {
358      return option
359        .toLowerCase()
360        .replace(/^(\s*)?(\/\/)?(http:\/\/|https:\/\/)?|(\/\S*\s*)|\s*$/g, "");
361    },
362  };
363
364  if (window.common_reg === undefined) {
365    window.common_reg = common_reg;
366  }
367
368  if (window.isWxMiniCodeWebviewEnv === undefined) {
369    window.isWxMiniCodeWebviewEnv =
370      navigator.userAgent.match(/miniprogram/i) ||
371      window.__wxjs_environment == "miniprogram";
372  }
373
374  $(document).ready(function () {
375    // $(function () {
376    //   FastClick.attach(document.body);
377    // });
378
379    toastr.options = {
380      closeButton: true,
381      debug: false,
382      newestOnTop: false,
383      progressBar: false,
384      positionClass: "toast-bottom-center",
385      preventDuplicates: false,
386      onclick: null,
387      showDuration: "300",
388      hideDuration: "1000",
389      timeOut: "5000",
390      extendedTimeOut: "1000",
391      showEasing: "swing",
392      hideEasing: "linear",
393      showMethod: "fadeIn",
394      hideMethod: "fadeOut",
395    };
396
397    //
398
399    $("#domain").attr(
400      "placeholder",
401      queryParams["server_type"] === "sslvpn"
402        ? "gm.trustasia.com:443(端口可选)"
403        : queryParams["server_type"] === "pqc_check"
404        ? "pqc.ssldemo.cn:443(端口可选)"
405        : "myssl.com:443(端口可选)"
406    );
407
408    function submitData() {
409      var search = $("#home-domain").val() || $("#domain").val() || "";
410      var checktype = $("#homepage_check_nav li.active").data("name");
411      var ipv = common_reg.ipv(search);
412      var domainv = common_reg.domain(search);
413      console.log(ipv, domainv, checktype);
414      if (domainv || ipv) {
415        var resulte = common_reg.result(search);
416        var domain = "";
417        var port = "";
418        if (resulte.indexOf(":") > -1) {
419          var temp = resulte.split(":");
420          domain = temp[0];
421          port = temp[1];
422        } else {
423          domain = resulte;
424        }
425        if (port * 1 < 65536 && port * 1 > 0) {
426          $("#report").append(
427            $(' <input name="port" type="hidden" value="' + port + '">')
428          );
429        }
430
431        if (
432          checktype == "sslvpn_check" ||
433          queryParams["server_type"] === "sslvpn"
434        ) {
435          $("#report").append(
436            $(' <input name="server_type" type="hidden" value="sslvpn">')
437          );
438        }
439
440        if (checktype == "ipv6_check") {
441          $("#report").append(
442            $(' <input name="ipv6" type="hidden" value="1">')
443          );
444        }
445
446        if (checktype == "pqc_check") {
447          window.open(
448            "/pqc_check.html?host=" + resulte + "&verify=0",
449            "_blank"
450          );
451        }
452
453        $("#home-domain").val(domain);
454        $("#domain").val(domain);
455        $("#report").prop({
456          action: domain,
457        });
458        $("#report").submit();
459      } else {
460        $("#cc-search").addClass("has-error");
461      }
462    }
463
464    $("#ssl-check").on("click", function (evt) {
465      submitData();
466    });
467
468    $("#main-ssl-check").on("click", function (evt) {
469      getInputHash();
470    });
471
472    $("#main-ssl-monitor").on("click", function (evt) {
473      var domain = $("#home-domain").val() || "";
474      // var baseUrl = "https://cm.myssl.com/user/login";
475      var hostname = "";
476
477      // 判断当前域名来决定跳转目标
478      if (window.location.hostname.indexOf("myssl.com") > -1) {
479        hostname = "https://cm.myssl.com";
480      } else {
481        hostname = "https://mycert.myssl.test";
482      }
483
484      var baseUrl = hostname + "/user/login";
485
486      if (domain) {
487        // 清理域名,移除协议和端口
488        var cleanDomain = common_reg.result(domain);
489        if (cleanDomain.indexOf(":") > -1) {
490          cleanDomain = cleanDomain.split(":")[0];
491        }
492
493        // 构建重定向URL
494        var redirectUrl =
495          hostname +
496          "/monitor?d=" +
497          encodeURIComponent(cleanDomain) +
498          "&s=1&from=myssl";
499        var finalUrl = baseUrl + "?redirect=" + encodeURIComponent(redirectUrl);
500
501        // 跳转到构建的URL
502        window.open(finalUrl, "_blank");
503      } else {
504        // 如果没有域名,直接跳转到登录页
505        window.open(baseUrl, "_blank");
506      }
507    });
508
509    $("#home-domain,#domain").on("focus", function () {
510      $("#cc-search").removeClass("has-error");
511    });
512
513    $('[data-toggle="tooltip"]').tooltip();
514
515    if ($("#issslvpn").val() === "sslvpn") {
516      $(".cc-left-breadcrumb ul.nav-pills li:gt(2)").addClass("disabled");
517      $(".cc-left-breadcrumb ul.nav-pills li:eq(5)").removeClass("disabled");
518    }
519
520    function forceRecheck() {
521      queryParams["f"] = 1;
522      if (queryParams.server_type === "sslvpn") {
523        queryParams["server_type"] = "sslvpn";
524      }
525      queryParams["status"] = "q";
526      delete queryParams["fc"];
527      delete queryParams["fdc"];
528      delete queryParams["reason"];
529      location.search = $.param(queryParams);
530    }
531
532    $(document).on("click", "#cc-renew-report", forceRecheck);
533    $(document).on("click", "#cc-onerror-recheck", forceRecheck);
534    $(document).on("mousemove", ".cc-index-topic", function () {
535      $(".cc-index-lets-check").animateCss("rubberBand");
536    });
537
538    setInterval(function () {
539      $(".cc-click-down span").animateCss("pulse");
540    }, 2000);
541
542    $(document).on("focus", "input", function () {
543      $(".cc-index-lets-check").animateCss("rubberBand");
544    });
545
546    $("input[name='domain']").bind("input propertychange", function (e) {
547      $("#domain-error").addClass("hidden");
548    });
549
550    // console.log(navigator.userAgent)
551
552    function myBrowser() {
553      var userAgent = navigator.userAgent; // 取得浏览器的userAgent字符串
554      var isOpera = userAgent.indexOf("Opera") > -1;
555      if (isOpera) {
556        return "Opera";
557      } // 判断是否Opera浏览器
558      if (userAgent.indexOf("Firefox") > -1) {
559        return "FF";
560      } // 判断是否Firefox浏览器
561      if (userAgent.indexOf("Chrome") > -1) {
562        return "Chrome";
563      }
564      if (userAgent.indexOf("Safari") > -1) {
565        return "Safari";
566      } // 判断是否Safari浏览器
567      if (
568        userAgent.indexOf("compatible") > -1 &&
569        userAgent.indexOf("MSIE") > -1 &&
570        !isOpera
571      ) {
572        return "IE";
573      } // 判断是否IE浏览器
574    }
575
576    // ie系列不支持svg动画
577    function JudgeBroswer() {
578      var temp = "";
579      var smalltemp = "";
580      var template = _.template(
581        '<div class="<%= sclass %> cc-loading">\
582        <div class="sk-circle1 sk-circle"></div>\
583        <div class="sk-circle2 sk-circle"></div>\
584        <div class="sk-circle3 sk-circle"></div>\
585        <div class="sk-circle4 sk-circle"></div>\
586        <div class="sk-circle5 sk-circle"></div>\
587        <div class="sk-circle6 sk-circle"></div>\
588        <div class="sk-circle7 sk-circle"></div>\
589        <div class="sk-circle8 sk-circle"></div>\
590        <div class="sk-circle9 sk-circle"></div>\
591        <div class="sk-circle10 sk-circle"></div>\
592        <div class="sk-circle11 sk-circle"></div>\
593        <div class="sk-circle12 sk-circle"></div>\
594      </div>'
595      );
596      var templateother = _.template(
597        '<div class="<%= sclass %>">\
598      <svg width="100%"  height="100%"  xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="lds-gooey-balls">\
599      <defs>\
600        <filter id="glue" x="-100%" y="-100%" width="300%" height="300%" color-interpolation-filters="sRGB">\
601          <feGaussianBlur in="SourceGraphic" stdDeviation="10"></feGaussianBlur>\
602          <feColorMatrix mode="matrix" values="1 0 0 0 0   0 1 0 0 0   0 0 1 0 0   0 0 0 60 -40" result="cm"></feColorMatrix>\
603        </filter>\
604      </defs>\
605      <g filter="url(#glue)">\
606        <circle cx="26.9894" cy="50" r="24.9894" fill="#f73003">\
607          <animate attributeName="r" calcMode="spline" values="18;25;18" keyTimes="0;0.5;1" dur="1" keySplines="0.5 0 0.5 1;0.5 0 0.5 1" begin="0s" repeatCount="indefinite"></animate>\
608          <animate attributeName="cx" calcMode="spline" values="20;27;20" keyTimes="0;0.5;1" dur="1" keySplines="0.5 0 0.5 1;0.5 0 0.5 1" begin="0s" repeatCount="indefinite"></animate>\
609        </circle>\
610        <circle cx="72.9894" cy="50" r="18.0106" fill="#54e404">\
611          <animate attributeName="r" calcMode="spline" values="25;18;25" keyTimes="0;0.5;1" dur="1" keySplines="0.5 0 0.5 1;0.5 0 0.5 1" begin="0s" repeatCount="indefinite"></animate>\
612          <animate attributeName="cx" calcMode="spline" values="66;73;66" keyTimes="0;0.5;1" dur="1" keySplines="0.5 0 0.5 1;0.5 0 0.5 1" begin="0s" repeatCount="indefinite"></animate>\
613        </circle>\
614      </g>\
615      </svg>\
616      </div>'
617      );
618      if ($.browser.msie || $.browser.msedge) {
619        temp = template({
620          sclass: "sk-fading-circle",
621        });
622        smalltemp = template({
623          sclass: "sk-fading-small-circle",
624        });
625        $(".cc-check-loading,.cc-check-cert-loading").html(temp);
626        $(".cc-small-loading").html(smalltemp);
627      } else {
628        temp = templateother({
629          sclass: "cc-svg-checking",
630        });
631        smalltemp = templateother({
632          sclass: "cc-small-svg-checking",
633        });
634        $(".cc-check-loading,.cc-check-cert-loading").html(temp);
635        $(".cc-small-loading").html(smalltemp);
636      }
637      // 以下是调用上面的函数
638      var mb = myBrowser();
639      if (mb == "IE") {
640        temp = template({
641          sclass: "sk-fading-circle",
642        });
643        smalltemp = template({
644          sclass: "sk-fading-small-circle",
645        });
646        $(".cc-check-loading,.cc-check-cert-loading").html(temp);
647        $(".cc-small-loading").html(smalltemp);
648      } else {
649        temp = templateother({
650          sclass: "cc-svg-checking",
651        });
652        smalltemp = templateother({
653          sclass: "cc-small-svg-checking",
654        });
655        $(".cc-check-loading,.cc-check-cert-loading").html(temp);
656        $(".cc-small-loading").html(smalltemp);
657      }
658    }
659    JudgeBroswer();
660
661    $(document).on("click", "#cc-myssl-seal", function () {
662      location.href = "/myssl.com?from=mysslid";
663    });
664
665    function changeSeal() {
666      var local = location.origin
667        ? location.origin
668        : location.protocol +
669          "//" +
670          location.hostname +
671          (location.port ? ":" + location.port : "");
672      var script =
673        "window.open('" +
674        local +
675        "/seal/detail?domain=" +
676        location.hostname +
677        "','MySSL安全签章','height=800,width=470,top=0,right=0,toolbar=no,menubar=no,scrollbars=no,resizable=no,location=no,status=no')";
678      var trustScript =
679        "window.open('https://seal.trustasia.com/seal/detail?domain=" +
680        location.hostname +
681        "','TrustAsia 安全签章','height=800,width=470,top=0,right=0,toolbar=no,menubar=no,scrollbars=no,resizable=no,location=no,status=no')";
682      var shell_info =
683        '<div title="MySSL安全签章" id="myssl_seal" onclick="' +
684        script +
685        '" style="text-align: center;display: inline-block"><img src="https://sealres.myssl.com/seal/img/2x/seal.png?domain=' +
686        location.hostname +
687        '" alt="' +
688        location.hostname +
689        '-MySSL安全签章" style="width: 100px; height: auto; cursor: pointer"></div>' +
690        '<div title="TrustAsia 安全签章" id="myssl_seal" onclick="' +
691        trustScript +
692        '" style="text-align: center;display: inline-block;height: 60px;"><img  src="https://sealres.trustasia.com/seal/img/1x/seal.png?domain=' +
693        location.hostname +
694        '" alt="TrustAsia 安全签章" style="width: 130px;height: auto; cursor: pointer; padding-top: 10px; margin-left: 14px"></div>' +
695        '<div class="itrust-seal" id="myssl_seal" style="display: inline-block"><a id="seal_knowsafe" href="https://www.knowsafe.com" sid="e06cba1fa15681d8745c41ddb34a37d7" slang="3" sdomain="https://seal.knowsafe.com" target="_blank">iTrust</a></div>';
696
697      var mimping_shell =
698        '<div title="TrustAsia 安全签章" id="myssl_seal" onclick="' +
699        trustScript +
700        '" style="text-align: center;display: inline-block;height: 60px;"><img  src="https://sealres.trustasia.com/seal/img/1x/seal.png?domain=' +
701        location.hostname +
702        '" alt="TrustAsia 安全签章" style="width: 130px;height: auto; cursor: pointer; padding-top: 14px;"></div>' +
703        '<div class="zhixun" id="zhixun" style="display: inline-block"><a href="http://www.zxcsec.com/"><img ' +
704        'src="https://static.myssl.com/res/images/zhixun.png?imageView2/0/w/720/interlace/1/q/75|imageslim" target="_blank" style="width: 55px; height: auto;padding-top: 10px; margin-left: 24px"' +
705        'alt="www.zxcsec.com" style="width: 34px"></a></div>';
706
707      $("#cc-myssl-id").html(shell_info);
708      $("#cc-miping-id").html(mimping_shell);
709      var idvalue = "";
710      var lang = "";
711      var domain = "";
712      try {
713        var jsl_speed_stat = document.getElementById("seal_knowsafe");
714        idvalue =
715          document.getElementById("seal_knowsafe").attributes["sid"].value;
716        lang =
717          document.getElementById("seal_knowsafe").attributes["slang"].value;
718        domain =
719          document.getElementById("seal_knowsafe").attributes["sdomain"].value;
720        jsl_speed_stat.style.display = "none";
721      } catch (err) {
722        var jsl_speed_stat = null;
723      }
724      $(".itrust-seal").html(
725        "<a target='_blank' href='" +
726          domain +
727          "/seal/itrustcert?id=" +
728          idvalue +
729          "&lang=" +
730          lang +
731          "' title='iTrust'><img style='width: 114px; height: auto;padding-top: 10px; margin-left: 14px' border='0' src='" +
732          domain +
733          "/seal/certimg?id=" +
734          idvalue +
735          "&lang=" +
736          lang +
737          "'></a>"
738      );
739    }
740
741    changeSeal();
742
743    $(document).on("click", "#cdn-check", function () {
744      goCDNcheck();
745    });
746
747    function goCDNcheck() {
748      var search = $("#home-domain").val() || "";
749      var domainv = common_reg.domain(search);
750      if (domainv) {
751        var resulte = common_reg.result(search);
752        var domain = "";
753        if (resulte.indexOf(":") > -1) {
754          var temp = resulte.split(":");
755          domain = temp[0];
756          port = temp[1];
757        } else {
758          domain = resulte;
759        }
760        $("#home-domain").val(domain);
761        location.href = "/cdn_check.html?domain=" + domain;
762      } else {
763        $("#cc-search").addClass("has-error");
764      }
765    }
766
767    $(document).ready(function () {
768      $("select").selectric({});
769      $("select,label").change(function () {
770        $("select").selectric({});
771      });
772    });
773
774    $(document).on("keypress", "#domain", function (evt) {
775      var keycode = evt.keyCode ? evt.keyCode : evt.which;
776      if (keycode == "13") {
777        evt.preventDefault();
778        submitData();
779      }
780    });
781
782    $(document).on("keypress", "#home-domain", function (evt) {
783      var keycode = evt.keyCode ? evt.keyCode : evt.which;
784      if (keycode == "13") {
785        evt.preventDefault();
786        getInputHash();
787      }
788    });
789
790    if ($.browser.mobile) {
791      $("input[name=domain],#common_name,#cc-email-domain").on(function (
792        event
793      ) {
794        event.preventDefault();
795      });
796    } else {
797      $("input[name=domain],#common_name,#cc-email-domain").focus();
798    }
799
800    function getInputHash() {
801      if ($("#homepage_check_nav li.cdn_check").hasClass("active")) {
802        goCDNcheck();
803      } else {
804        submitData();
805      }
806    }
807
808    function findLocationHash(lhash) {
809      $("#homepage_check_nav ." + lhash)
810        .addClass("active")
811        .siblings("li")
812        .removeClass("active");
813      if (lhash == "sslvpn_check") {
814        $(".cc-gm-placeholder").css("display", "block");
815        $(".cc-normal-placeholder").css("display", "none");
816      } else {
817        $(".cc-gm-placeholder").css("display", "none");
818        $(".cc-normal-placeholder").css("display", "block");
819      }
820      if (lhash === "email_check") {
821        $("#home-domain").attr("placeholder", "smtp.qq.com:465");
822        $("#home-domain").val("smtp.qq.com:465");
823      } else if (lhash == "sslvpn_check") {
824        $("#home-domain").attr("placeholder", "gm.trustasia.com");
825        $("#home-domain").val("gm.trustasia.com");
826      } else if (lhash == "pqc_check") {
827        $("#home-domain").attr("placeholder", "pqc.ssldemo.cn");
828        $("#home-domain").val("pqc.ssldemo.cn");
829      } else {
830        $("#home-domain").attr("placeholder", "myssl.com");
831        $("#home-domain").val("");
832      }
833
834      // $(this).attr('placeholder',"");
835      // $('.tab-content .' + lhash).addClass('active').siblings('div').removeClass('active');
836    }
837
838    $("#homepage_check_nav li a").on("click", function () {
839      var lhash = $(this).attr("alt");
840      findLocationHash(lhash);
841    });
842
843    if (location.hash && location.hash == "#gmssl") {
844      $("#homepage_check_nav .sslvpn_check")
845        .addClass("active")
846        .siblings("li")
847        .removeClass("active");
848      $(".cc-gm-placeholder").css("display", "block");
849      $(".cc-normal-placeholder").css("display", "none");
850      $("#home-domain").attr("placeholder", "gm.trustasia.com");
851      $("#home-domain").val("gm.trustasia.com");
852    }
853
854    // $('#cc-navbar-collapse') 整个大nav
855    // headingOne  collapseOne  工具箱
856    // second-level-btn collapseContain 工具箱下的第二层
857
858    function fixCollpse() {
859      if ($(window).width() > 768) {
860        $("#cc-navbar-collapse,.collapseContain").show();
861      } else if ($(window).width() < 768) {
862        $("#cc-navbar-collapse,.collapseContain,#collapseOne").hide();
863      }
864    }
865
866    fixCollpse();
867
868    $(document).on("click", ".cc-navbar-btn", function (e) {
869      $("#cc-navbar-collapse").toggle();
870    });
871
872    $(document).on("click", "#cc-navbar-collapse", function (e) {
873      e.stopPropagation();
874    });
875
876    $(window).resize(function () {
877      fixCollpse();
878    });
879
880    $(document).on("click", "#headingOne", function (e) {
881      $("#collapseOne").toggle();
882
883      $(document).one("click", function () {
884        $("#collapseOne").hide();
885      });
886      e.stopPropagation();
887    });
888
889    $(document).on("click", "#collapseOne", function (e) {
890      e.stopPropagation();
891    });
892
893    $(document).on("click", ".second-level-btn", function (e) {
894      e.stopPropagation();
895      $(this).parent("div").siblings(".collapseContain").toggle();
896    });
897
898    $("#domain-error-close").on("click", function () {
899      $("#domain-error").addClass("hidden");
900    });
901
902    $(
903      "#cc-upload-text,#cc-upload-text-other,#cc-todecrypt-text, #cc-decrypt-text, #cc-totc-text,#cc-evelope-text,#cc-key-text,#cc-key-temp-text, #cc-tc-text, #cc-gmtodecrypt-text, #cc-gmdecrypt-text"
904    ).on({
905      focus: function (param) {
906        $(this).next("div").hide();
907        $(".cc-upload-box input").val() == "";
908      },
909      blur: function (param) {
910        $(".cc-upload-box input").val() == "";
911        if ($(this).val() == "") {
912          $(this).next("div").show();
913        } else if ($(this).val() !== "") {
914          $(this).next("div").hide();
915        }
916      },
917    });
918
919    $(document).on("click", ".copy-btn", function (e) {
920      e.stopPropagation();
921      var text = $(this).attr("data-clipboard-text");
922      var $btn = $(this);
923
924      navigator.clipboard
925        .writeText(text)
926        .then(function () {
927          var originalText = $btn.text();
928          $btn.text("已复制!");
929          $btn.addClass("copied");
930
931          setTimeout(function () {
932            $btn.text(originalText);
933            $btn.removeClass("copied");
934          }, 2000);
935        })
936        .catch(function (err) {
937          console.error("复制失败:", err);
938        });
939    });
940
941    // KeyManager 智能下载功能
942    $(document).on("click", "#keymanager-main-download-btn", function (e) {
943      e.preventDefault();
944      window.KeyManagerDownload.downloadKeyManager(null, this);
945    });
946
947    // Mac 用户:初始化芯片选择下载链接
948    window.KeyManagerDownload.initMacDownloadLinks();
949
950    // 页面就绪即预拉取最新版本号,点击下载时无需等待
951    window.KeyManagerDownload.preloadVersion();
952
953    $(document).on("click", ".km-mac-download", function (e) {
954      e.preventDefault();
955      var chip = $(this).data("chip");
956      window.KeyManagerDownload.downloadKeyManager(chip, this);
957    });
958  });
959
960  // KeyManager 公共下载功能
961  window.KeyManagerDownload = {
962    // 平台检测函数
963    detectPlatform: function() {
964      var userAgent = navigator.userAgent.toLowerCase();
965      var platform = navigator.platform.toLowerCase();
966
967      return {
968        macos: /mac/.test(platform) || /macintosh/.test(userAgent),
969        windows: /win/.test(platform) || /windows/.test(userAgent),
970        linux: /linux/.test(platform) || /x11/.test(platform),
971      };
972    },
973
974    // 简单的YAML解析函数
975    parseYAML: function(yamlText) {
976      var lines = yamlText.split("\n");
977      var result = {};
978
979      lines.forEach(function (line) {
980        var trimmedLine = line.trim();
981        if (trimmedLine && !trimmedLine.startsWith("#")) {
982          var colonIndex = trimmedLine.indexOf(":");
983          if (colonIndex > 0) {
984            var key = trimmedLine.substring(0, colonIndex).trim();
985            var value = trimmedLine.substring(colonIndex + 1).trim();
986            result[key] = value;
987          }
988        }
989      });
990
991      return result;
992    },
993
994    // Mac 用户:初始化芯片选择下载链接,替换页面上所有 KeyManager 下载入口
995    initMacDownloadLinks: function() {
996      var platform = this.detectPlatform();
997      if (!platform.macos) return;
998
999      $("#keymanager-main-download-btn").each(function() {
1000        var $link = $(this);
1001        var $replacement = $('<span class="km-mac-chip-links"></span>');
1002        $replacement.append(
1003          '<span class="glyphicon glyphicon-download-alt"></span> 下载 KeyManager:'
1004        );
1005        $replacement.append(
1006          '<a href="#" class="km-mac-download keymanager-download-link" data-chip="intel">Intel 芯片版</a>'
1007        );
1008        $replacement.append(" / ");
1009        $replacement.append(
1010          '<a href="#" class="km-mac-download keymanager-download-link" data-chip="apple">Apple 芯片版</a>'
1011        );
1012        $link.replaceWith($replacement);
1013      });
1014
1015      $("#keymanager-download-btn").each(function() {
1016        var $link = $(this);
1017        var $replacement = $('<span class="km-mac-chip-links"></span>');
1018        $replacement.append(
1019          '<a href="#" class="km-mac-download keymanager-download-link" data-chip="intel">Intel 芯片版</a>'
1020        );
1021        $replacement.append(" / ");
1022        $replacement.append(
1023          '<a href="#" class="km-mac-download keymanager-download-link" data-chip="apple">Apple 芯片版</a>'
1024        );
1025        $link.replaceWith($replacement);
1026      });
1027    },
1028
1029    // 预加载状态:缓存进行中或已完成的版本号请求,避免点击时再发一次
1030    _versionPromise: null,
1031
1032    // 预拉取最新版本号;失败时清掉缓存以便下次重试
1033    preloadVersion: function () {
1034      var self = this;
1035      if (self._versionPromise) return self._versionPromise;
1036
1037      self._versionPromise = new Promise(function (resolve, reject) {
1038        var xhr = new XMLHttpRequest();
1039        var apiUrl =
1040          "https://keymanager.trustasia.com/release/latest.yml?refresh=" +
1041          Date.parse(new Date());
1042
1043        xhr.open("GET", apiUrl, true);
1044        xhr.onreadystatechange = function () {
1045          if (xhr.readyState !== XMLHttpRequest.DONE) return;
1046          if (xhr.status !== 200) {
1047            reject(new Error("HTTP " + xhr.status));
1048            return;
1049          }
1050          try {
1051            var yamlData = self.parseYAML(xhr.responseText);
1052            if (yamlData.version) {
1053              resolve(yamlData.version);
1054            } else {
1055              reject(new Error("无法解析版本信息"));
1056            }
1057          } catch (err) {
1058            reject(err);
1059          }
1060        };
1061        xhr.onerror = function () {
1062          reject(new Error("网络请求失败"));
1063        };
1064        xhr.send();
1065      });
1066
1067      self._versionPromise.catch(function (err) {
1068        console.error("预加载 KeyManager 版本失败:", err);
1069        self._versionPromise = null;
1070      });
1071
1072      return self._versionPromise;
1073    },
1074
1075    // 根据版本号与芯片类型构建对应平台的下载链接
1076    buildDownloadUrl: function (version, chip) {
1077      var platform = this.detectPlatform();
1078      var baseUrl = "https://keymanager.trustasia.com/release/";
1079
1080      if (platform.macos) {
1081        return chip === "apple"
1082          ? baseUrl + "KeyManager-" + version + "-arm64.dmg"
1083          : baseUrl + "KeyManager-" + version + ".dmg";
1084      }
1085      if (platform.linux) {
1086        return baseUrl + "KeyManager-" + version + ".AppImage";
1087      }
1088      return baseUrl + "KeyManager-Setup-" + version + ".exe";
1089    },
1090
1091    // KeyManager下载函数,chip 参数仅 Mac 使用:'intel' 或 'apple'
1092    downloadKeyManager: function (chip, triggerElement) {
1093      var self = this;
1094      var $btn = triggerElement
1095        ? $(triggerElement)
1096        : $("#keymanager-main-download-btn");
1097      var originalText = $btn.text();
1098
1099      var versionPromise = self.preloadVersion();
1100
1101      // 若预加载尚未完成则展示加载态,命中缓存时跳过以避免文字闪烁
1102      var settled = false;
1103      var loadingTimer = setTimeout(function () {
1104        if (!settled) {
1105          $btn.text("正在获取最新版本...").css("pointer-events", "none");
1106        }
1107      }, 0);
1108
1109      versionPromise
1110        .then(function (version) {
1111          settled = true;
1112          clearTimeout(loadingTimer);
1113          var downloadUrl = self.buildDownloadUrl(version, chip);
1114          $btn.text("正在下载...").css("pointer-events", "none");
1115          window.open(downloadUrl, "_blank");
1116          setTimeout(function () {
1117            $btn.text(originalText).css("pointer-events", "");
1118          }, 2000);
1119        })
1120        .catch(function (err) {
1121          settled = true;
1122          clearTimeout(loadingTimer);
1123          console.error("KeyManager 下载失败:", err);
1124          $btn.text("下载失败,请重试").css("pointer-events", "");
1125          setTimeout(function () {
1126            $btn.text(originalText).css("pointer-events", "");
1127          }, 3000);
1128        });
1129    },
1130  };
1131})(window);
1132
1133//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlcyI6WyJtYWluLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIHJlcXVpcmUtanNkb2MgKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXZhciAqL1xuLyogZXNsaW50LWRpc2FibGUgc3BhY2UtYmVmb3JlLWZ1bmN0aW9uLXBhcmVuICovXG4vKiBlc2xpbnQtZGlzYWJsZSBxdW90ZXMgKi9cbi8qIGVzbGludC1kaXNhYmxlIG9uZS12YXIgKi9cbi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLyogZXNsaW50LWRpc2FibGUgZ3VhcmQtZm9yLWluICovXG4vKiAhXG4gKlxuICogIG15c3NsLmNvbVxuICogIENvcHlyaWdodCAyMDE1IEdvb2dsZSBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiAgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2VcbiAqXG4gKi9cbi8qIGVzbGludC1lbnYgYnJvd3NlciAqL1xuXG4oZnVuY3Rpb24gKHdpbmRvdykge1xuICBcInVzZSBzdHJpY3RcIjtcbiAgLyogXFxcbiAgfCp8XG4gIHwqfCAgOjogTWluaURhZW1vbiA6OlxuICB8KnxcbiAgfCp8ICBSZXZpc2lvbiAjMiAtIFNlcHRlbWJlciAyNiwgMjAxNFxuICB8KnxcbiAgfCp8ICBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvd2luZG93LnNldEludGVydmFsXG4gIHwqfCAgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvVXNlcjpmdXNpb25jaGVzc1xuICB8KnwgIGh0dHBzOi8vZ2l0aHViLmNvbS9tYWRtdXJwaHkvbWluaWRhZW1vbi5qc1xuICB8KnxcbiAgfCp8ICBUaGlzIGZyYW1ld29yayBpcyByZWxlYXNlZCB1bmRlciB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLCB2ZXJzaW9uIDMgb3IgbGF0ZXIuXG4gIHwqfCAgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2xncGwtMy4wLmh0bWxcbiAgfCp8XG4gIFxcKi9cblxuICBmdW5jdGlvbiBNaW5pRGFlbW9uKG9Pd25lciwgZlRhc2ssIG5SYXRlLCBuTGVuKSB7XG4gICAgaWYgKCEodGhpcyAmJiB0aGlzIGluc3RhbmNlb2YgTWluaURhZW1vbikpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTWluaURhZW1vbiAtIG5vdCBlbm91Z2ggYXJndW1lbnRzXCIpO1xuICAgIH1cbiAgICBpZiAob093bmVyKSB7XG4gICAgICB0aGlzLm93bmVyID0gb093bmVyO1xuICAgIH1cbiAgICB0aGlzLnRhc2sgPSBmVGFzaztcbiAgICBpZiAoaXNGaW5pdGUoblJhdGUpICYmIG5SYXRlID4gMCkge1xuICAgICAgdGhpcy5yYXRlID0gTWF0aC5mbG9vcihuUmF0ZSk7XG4gICAgfVxuICAgIGlmIChuTGVuID4gMCkge1xuICAgICAgdGhpcy5sZW5ndGggPSBNYXRoLmZsb29yKG5MZW4pO1xuICAgIH1cbiAgfVxuXG4gIE1pbmlEYWVtb24ucHJvdG90eXBlLm93bmVyID0gbnVsbDtcbiAgTWluaURhZW1vbi5wcm90b3R5cGUudGFzayA9IG51bGw7XG4gIE1pbmlEYWVtb24ucHJvdG90eXBlLnJhdGUgPSAxMDA7XG4gIE1pbmlEYWVtb24ucHJvdG90eXBlLmxlbmd0aCA9IEluZmluaXR5O1xuXG4gIC8qIFRoZXNlIHByb3BlcnRpZXMgc2hvdWxkIGJlIHJlYWQtb25seSAqL1xuXG4gIE1pbmlEYWVtb24ucHJvdG90eXBlLlNFU1NJT04gPSAtMTtcbiAgTWluaURhZW1vbi5wcm90b3R5cGUuSU5ERVggPSAwO1xuICBNaW5pRGFlbW9uLnByb3RvdHlwZS5QQVVTRUQgPSB0cnVlO1xuICBNaW5pRGFlbW9uLnByb3RvdHlwZS5CQUNLVyA9IHRydWU7XG5cbiAgLyogR2xvYmFsIG1ldGhvZHMgKi9cblxuICBNaW5pRGFlbW9uLmZvcmNlQ2FsbCA9IGZ1bmN0aW9uIChvRG1uKSB7XG4gICAgb0Rtbi5JTkRFWCArPSBvRG1uLkJBQ0tXID8gLTEgOiAxO1xuICAgIGlmIChcbiAgICAgIG9EbW4udGFzay5jYWxsKG9EbW4ub3duZXIsIG9EbW4uSU5ERVgsIG9EbW4ubGVuZ3RoLCBvRG1uLkJBQ0tXKSA9PT1cbiAgICAgICAgZmFsc2UgfHxcbiAgICAgIG9EbW4uaXNBdEVuZCgpXG4gICAgKSB7XG4gICAgICBvRG1uLnBhdXNlKCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybi
1133B0cnVlO1xuICB9O1xuXG4gIC8qIEluc3RhbmNlcyBtZXRob2RzICovXG5cbiAgTWluaURhZW1vbi5wcm90b3R5cGUuaXNBdEVuZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5CQUNLV1xuICAgICAgPyBpc0Zpbml0ZSh0aGlzLmxlbmd0aCkgJiYgdGhpcy5JTkRFWCA8IDFcbiAgICAgIDogdGhpcy5JTkRFWCArIDEgPiB0aGlzLmxlbmd0aDtcbiAgfTtcblxuICBNaW5pRGFlbW9uLnByb3RvdHlwZS5zeW5jaHJvbml6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5QQVVTRUQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY2xlYXJJbnRlcnZhbCh0aGlzLlNFU1NJT04pO1xuICAgIHRoaXMuU0VTU0lPTiA9IHNldEludGVydmFsKE1pbmlEYWVtb24uZm9yY2VDYWxsLCB0aGlzLnJhdGUsIHRoaXMpO1xuICB9O1xuXG4gIE1pbmlEYWVtb24ucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24gKCkge1xuICAgIGNsZWFySW50ZXJ2YWwodGhpcy5TRVNTSU9OKTtcbiAgICB0aGlzLlBBVVNFRCA9IHRydWU7XG4gIH07XG5cbiAgTWluaURhZW1vbi5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbiAoYlJldmVyc2UpIHtcbiAgICB2YXIgYkJhY2t3ID0gQm9vbGVhbihiUmV2ZXJzZSk7XG4gICAgaWYgKHRoaXMuQkFDS1cgPT09IGJCYWNrdyAmJiAodGhpcy5pc0F0RW5kKCkgfHwgIXRoaXMuUEFVU0VEKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLkJBQ0tXID0gYkJhY2t3O1xuICAgIHRoaXMuUEFVU0VEID0gZmFsc2U7XG4gICAgdGhpcy5zeW5jaHJvbml6ZSgpO1xuICB9O1xuXG4gIGlmICh3aW5kb3cuTWluaURhZW1vbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgd2luZG93Lk1pbmlEYWVtb24gPSBNaW5pRGFlbW9uO1xuICB9XG5cbiAgLy8g5aKe5Yqg5Y+C5pWw6aqM6K+B5ZKM6L+H5rukXG5cbiAgdmFyIHBhcmFtc0ZpbHRlciA9IHtcbiAgICAvLyBcImRvbWFpblwiOiAvXihbXFxTXStbXFxTXSpcXC5bXFxTXXsyLDR9KXwoKD8hMCkoPyEuKlxcLiQpKCgxP1xc
1133ZD9cXGR8MjVbMC01XXwyWzAtNF1cXGQpKFxcLnwkKSl7NH0pJC9pZyxcbiAgICBpcDogL14oPyEwKSg/IS4qXFwuJCkoKDE/XFxkP1xcZHwyNVswLTVdfDJbMC00XVxcZCkoXFwufCQpKXs0fSQvZ2ksXG4gICAgZjogL15cXGQqJC9naSxcbiAgICBwb3J0OiAvXlxcZHsxLDV9JC9naSxcbiAgICBleHQ6IC9eXFxkKiQvZ2ksXG4gICAgaGlkZTogL15cXGQqJC9naSxcbiAgfTtcblxuICAvLyB2YXIgZ2V0UGFyYW1zQXNPYmplY3QgPSBmdW5jdGlvbiAocXVlcnkpIHtcbiAgLy8gICBxdWVyeSA9IHF1ZXJ5LnN1YnN0cmluZyhxdWVyeS5pbmRleE9mKFwiP1wiKSArIDEpO1xuICAvLyAgIHZhciByZSA9IC8oW14mPV0rKT0/KFteJl0qKS9nO1xuICAvLyAgIHZhciBkZWNvZGVSRSA9IC9cXCsvZztcbiAgLy8gICB2YXIgZGVjb2RlID0gZnVuY3Rpb24gKHN0cikge1xuICAvLyAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChzdHIucmVwbGFjZShkZWNvZGVSRSwgXCIgXCIpKTtcbiAgLy8gICB9O1xuICAvLyAgIHZhciBwYXJhbXMgPSB7fSxcbiAgLy8gICAgIGU7XG4gIC8vICAgd2hpbGUgKChlID0gcmUuZXhlYyhxdWVyeSkpKSB7XG4gIC8vICAgICB2YXIgayA9IGRlY29kZShlWzFdKTtcbiAgLy8gICAgIHZhciB2ID0gZGVjb2RlKGVbMl0pIHx8IFwiXCI7XG4gIC8vICAgICAvLyDov5nph4zlgZrlj4LmlbDmoKHpqoxcbiAgLy8gICAgIHZhciB0ZW1wX3ZhbGlkYXRpb24gPSBwYXJhbXNGaWx0ZXJba107XG4gIC8vICAgICB2YXIgdGVtcF9yZSA9IHYubWF0Y2godGVtcF92YWxpZGF0aW9uKSB8fCBcIlwiO1xuICAvLyAgICAgaWYgKHRlbXBfcmUubGVuZ3RoICYmIHRlbXBfcmVbMF0pIHtcbiAgLy8gICAgICAgdiA9IHRlbXBfcmVbMF07XG4gIC8vICAgICB9XG4gIC8vICAgICBpZiAoay5zdWJzdHJpbmcoay5sZW5ndGggLSAyKSA9PT0gXCJbXVwiKSB7XG4gIC8vICAgICAgIGsgPSBrLnN1YnN0cmluZygwLCBrLmxlbmd0aCAtIDIpO1xuICAvLyAgICAgICAocGFyYW1zW2tdIHx8IChwYXJhbXNba10gPSBbXSkpLnB1c2godik7XG4gIC8vICAgICB9IGVsc2Uge1xuICAvLyAgICAgICBwYXJhbXNba10gPSB2O1xuICAvLyAgICAgfVxuICAvLyAgIH1cblxuICAvLyAgIC8vIOS4i+mdouS4pOauteS7o+eggeS8muW8lei1tyB4c3PmvI/mtJ7vvIzmhY7nlKhcbiAgLy8gICB2YXIgYXNzaWduID0gZnVuY3Rpb24gKG9iaiwga2V5UGF0aCwgdmFsdWUpIHtcbiAgLy8gICAgIHZhciBsYXN0S2V5SW5kZXggPSBrZXlQYXRoLmxlbmd0aCAtIDE7XG4gIC8vICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxhc3RLZXlJbmRleDsgKytpKSB7XG4gIC8vICAgICAgIHZhciBrZXkgPSBrZXlQYXRoW2ldO1xuICAvLyAgICAgICBpZiAoIShrZXkgaW4gb2JqKSkgb2JqW2tleV0gPSB7fTtcbiAgLy8gICAgICAgb2JqID0gb2JqW2tleV07XG4gIC8vICAgICB9XG4gIC8vICAgICBvYmpba2V5UGF0aFtsYXN0S2V5SW5kZXhdXSA9IHZhbHVlO1xuICAvLyAgIH07XG5cbiAgLy8gICBmb3IgKHZhciBwcm9wIGluIHBhcmFtcykge1xuICAvLyAgICAgdmFyIHN0cnVjdHVyZSA9IHByb3Auc3BsaXQoXCJbXCIpO1xuICAvLyAgICAgaWYgKHN0cnVjdHVyZS5sZW5ndGggPiAxKSB7XG4gIC8vICAgICAgIHZhciBsZXZlbHMgPSBbXTtcbiAgLy8gICAgICAgc3RydWN0dXJlLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0sIGkpIHtcbiAgLy8gICAgICAgICB2Y
1133XIga2V5ID0gaXRlbS5yZXBsYWNlKC9bP1tcXF1cXFxcIF0vZywgXCJcIik7XG4gIC8vICAgICAgICAgbGV2ZWxzLnB1c2goa2V5KTtcbiAgLy8gICAgICAgfSk7XG4gIC8vICAgICAgIGFzc2lnbihwYXJhbXMsIGxldmVscywgcGFyYW1zW3Byb3BdKTtcbiAgLy8gICAgICAgZGVsZXRlIHBhcmFtc1twcm9wXTtcbiAgLy8gICAgIH1cbiAgLy8gICB9XG4gIC8vICAgY29uc29sZS5sb2cocGFyYW1zKTtcbiAgLy8gICByZXR1cm4gcGFyYW1zO1xuICAvLyB9O1xuXG4gIHZhciBuZXdHZXRQYXJhbXNBc09iamVjdCA9IGZ1bmN0aW9uIChxdWVyeSkge1xuICAgIHF1ZXJ5ID0gcXVlcnkuc3Vic3RyaW5nKHF1ZXJ5LmluZGV4T2YoXCI/XCIpICsgMSk7XG5cbiAgICB2YXIgcmUgPSAvKFteJj1dKyk9PyhbXiZdKikvZztcbiAgICB2YXIgZGVjb2RlUkUgPSAvXFwrL2c7XG5cbiAgICB2YXIgZGVjb2RlID0gZnVuY3Rpb24gKHN0cikge1xuICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChzdHIucmVwbGFjZShkZWNvZGVSRSwgXCIgXCIpKTtcbiAgICB9O1xuXG4gICAgdmFyIHBhcmFtcyA9IHt9LFxuICAgICAgZTtcbiAgICB3aGlsZSAoKGUgPSByZS5leGVjKHF1ZXJ5KSkpIHtcbiAgICAgIHZhciBrID0gZGVjb2RlKGVbMV0pO1xuICAgICAgdmFyIHYgPSBkZWNvZGUoZVsyXSkgfHwgXCJcIjtcbiAgICAgIC8vIOi/memHjOWBmuWPguaVsOagoemqjFxuICAgICAgdmFyIHRlbXBfdmFsaWRhdGlvbiA9IHBhcmFtc0ZpbHRlcltrXTtcbiAgICAgIHZhciB0ZW1wX3JlID0gdi5tYXRjaCh0ZW1wX3ZhbGlkYXRpb24pIHx8IFwiXCI7XG4gICAgICBpZiAodGVtcF9yZS5sZW5ndGggJiYgdGVtcF9yZVswXSkge1xuICAgICAgICB2ID0gdGVtcF9yZVswXTtcbiAgICAgIH1cbiAgICAgIGlmIChrLnN1YnN0cmluZyhrLmxlbmd0aCAtIDIpICE9PSBcIltdXCIpIHtcbiAgICAgICAgcGFyYW1zW2tdID0gdjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcGFyYW1zO1xuICB9O1xuXG4gIHdpbmRvdy5xdWVyeVBhcmFtcyA9IG5ld0dldFBhcmFtc0FzT2JqZWN0KGxvY2F0aW9uLnNlYXJjaCk7XG4gIC8vIC8vIENoZWNrIHRvIG1ha2Ugc3VyZSBzZXJ2aWNlIHdvcmtlcnMgYXJlIHN1cHBvcnRlZCBpbiB0aGUgY3VycmVudCBicm93c2VyLFxuICAvLyAvLyBhbmQgdGhhdCB0aGUgY3VycmVudCBwYWdlIGlzIGFjY2Vzc2VkIGZyb20gYSBzZWN1cmUgb3JpZ2luLiBVc2luZyBhXG4gIC8vIC8vIHNlcnZpY2Ugd29ya2VyIGZyb20gYW4gaW5zZWN1cmUgb3JpZ2luIHdpbGwgdHJpZ2dlciBKUyBjb25zb2xlIGVycm9ycy4gU2VlXG4gIC8vIC8vIGh0dHA6Ly93d3cuY2hyb21pdW0ub3JnL0hvbWUvY2hyb21pdW0tc2VjdXJpdHkvcHJlZmVyLXNlY3VyZS1vcmlnaW5zLWZvci1wb3dlcmZ1bC1uZXctZmVhdHVyZXNcbiAgLy8gdmFyIGlzTG9jYWxob3N0ID0gQm9vbGVhbih3aW5kb3cubG9jYXRpb24uaG9zdG5hbWUgPT09ICdsb2NhbGhvc3QnIHx8XG4gIC8vICAgICAvLyBbOjoxXSBpcyB0aGUgSVB2NiBsb2NhbGhvc3QgYWRkcmVzcy5cbiAgLy8gICAgIHdpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZSA9PT0gJ1s6OjFdJyB8fFxuICAvLyAgICAgLy8gMTI3LjAuMC4xLzggaXMgY29uc2lkZXJlZCBsb2NhbGhvc3QgZm9yIElQdjQuXG4gIC8vICAgICB3aW5kb3cubG9jYXRpb24uaG9zdG5hbWUubWF0Y2goXG4gIC8vICAgICAgIC9eMTI3KD86XFwuKD86MjVbMC01XXwyWzAtNF1bMC05XXxbMDFdP1swLTldWzAtOV0/KSl7M30kL1xuICAvLyAgICAgKVxuICAvLyAgICk7XG4gIC8vXG4gIC8vIGlmICgnc2VydmljZVdvcmtlcicgaW4gbmF2aWdhdG9yICYmXG4gIC8vICAgICAod2luZG93LmxvY2F0aW9uLnByb3RvY29sID09PSAnaHR0cHM6JyB8fCBpc0xvY2FsaG9zdCkpIHtcbiAgLy8gICBuYXZpZ2F0b3Iuc2VydmljZVdvcmtlci5yZWdpc3Rlcignc2VydmljZS13b3JrZXIuanMnKVxuICAvLyAgIC50aGVuKGZ1bmN0aW9uKHJlZ2lzdHJhdGlvbikge1xuICAvLyAgICAgLy8gdXBkYXRlZm91bmQgaXMgZmlyZWQgaWYgc2VydmljZS13b3JrZXIuanMgY2hhbmdlcy5cbiAgLy8gICAgIHJlZ2lzdHJhdGlvbi5vbnVwZGF0ZWZvdW5kID0gZnVuY3Rpb24oKSB7XG4gIC8vICAgICAgIC8vIHVwZGF0ZWZvdW5kIGlzIGFsc28gZmlyZWQgdGhlIHZlcnkgZmlyc3QgdGltZSB0aGUgU1cgaXMgaW5zdGFsbGVkLFxuICAvLyAgICAgICAvLyBhbmQgdGhlcmUncyBubyBuZWVkIHRvIHByb21wdCBmb3IgYSByZWxvYWQgYXQgdGhhdCBwb2ludC5cbiAgLy8gICAgICAgLy8gU28gY2hlY2sgaGVyZSB0byBzZWUgaWYgdGhlIHBhZ2UgaXMgYWxyZWFkeSBjb250cm9sbGVkLFxuICAvLyAgICAgICAvLyBpLmUuIHdoZXRoZXIgdGhlcmUncyBhbiBleGlzdGluZyBzZXJ2aWNlIHdvcmtlci5cbiAgLy8gICAgICAgaWYgKG5hdmlnYXRvci5zZXJ2aWNlV29ya2VyLmNvbnRyb2xsZXIpIHtcbiAgLy8gICAgICAgICAvLyBUaGUgdXBkYXRlZm91bmQgZXZlbnQgaW1wbGllcyB0aGF0IHJlZ2lzdHJhdGlvbi5pbnN0YWxsaW5nIGlzIHNldDpcbiAgLy8gICAgICAgICAvLyBodHRwczovL3NsaWdodGx5b2ZmLmdpdGh1Yi5pby9TZXJ2aWNlV29ya2VyL3NwZWMvc2VydmljZV93b3JrZXIvaW5kZXguaHRtbCNzZXJ2aWNlLXdvcmtlci1jb250YWluZXItdXBkYXRlZm91bmQtZXZlbnRcbiAgLy8gICAgICAgICB2Y
1133XIgaW5zdGFsbGluZ1dvcmtlciA9IHJlZ2lzdHJhdGlvbi5pbnN0YWxsaW5nO1xuICAvL1xuICAvLyAgICAgICAgIGluc3RhbGxpbmdXb3JrZXIub25zdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAvLyAgICAgICAgICAgc3dpdGNoIChpbnN0YWxsaW5nV29ya2VyLnN0YXRlKSB7XG4gIC8vICAgICAgICAgICAgIGNhc2UgJ2luc3RhbGxlZCc6XG4gIC8vICAgICAgICAgICAgICAgLy8gQXQgdGhpcyBwb2ludCwgdGhlIG9sZCBjb250ZW50IHdpbGwgaGF2ZSBiZWVuIHB1cmdlZCBhbmQgdGhlXG4gIC8vICAgICAgICAgICAgICAgLy8gZnJlc2ggY29udGVudCB3aWxsIGhhdmUgYmVlbiBhZGRlZCB0byB0aGUgY2FjaGUuXG4gIC8vICAgICAgICAgICAgICAgLy8gSXQncyB0aGUgcGVyZmVjdCB0aW1lIHRvIGRpc3BsYXkgYSBcIk5ldyBjb250ZW50IGlzXG4gIC8vICAgICAgICAgICAgICAgLy8gYXZhaWxhYmxlOyBwbGVhc2UgcmVmcmVzaC5cIiBtZXNzYWdlIGluIHRoZSBwYWdlJ3MgaW50ZXJmYWNlLlxuICAvLyAgICAgICAgICAgICAgIGJyZWFrO1xuICAvL1xuICAvLyAgICAgICAgICAgICBjYXNlICdyZWR1bmRhbnQnOlxuICAvLyAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGluc3RhbGxpbmcgJyArXG4gIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzZXJ2aWNlIHdvcmtlciBiZWNhbWUgcmVkdW5kYW50LicpO1xuICAvL1xuICAvLyAgICAgICAgICAgICBkZWZhdWx0OlxuICAvLyAgICAgICAgICAgICAgIC8vIElnbm9yZVxuICAvLyAgICAgICAgICAgfVxuICAvLyAgICAgICAgIH07XG4gIC8vICAgICAgIH1cbiAgLy8gICAgIH07XG4gIC8vICAgfSkuY2F0Y2goZnVuY3Rpb24oZSkge1xuICAvLyAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZHVyaW5nIHNlcnZpY2Ugd29ya2VyIHJlZ2lzdHJhdGlvbj
1133onLCBlKTtcbiAgLy8gICB9KTtcbiAgLy8gfVxuXG4gIC8vIFlvdXIgY3VzdG9tIEphdmFTY3JpcHQgZ29lcyBoZXJlXG5cbiAgdmFyIHRhTG9jayA9IHtcbiAgICBfX2NvdW50X186IDAsXG4gICAgX191bmxvY2tlZF9fOiB0cnVlLFxuICAgIGxvY2s6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMuX19jb3VudF9fICs9IDE7XG4gICAgICB0aGlzLl9fdW5sb2NrZWRfXyA9IGZhbHNlO1xuICAgIH0sXG4gICAgZnJlZTogZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHRoaXMuX19jb3VudF9fID4gMCkge1xuICAgICAgICB0aGlzLl9fY291bnRfXyAtPSAxO1xuICAgICAgfVxuICAgICAgdGhpcy5fX3VubG9ja2VkX18gPSB0cnVlO1xuICAgIH0sXG4gICAgaXNfbG9ja2VkOiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gIXRoaXMuX191bmxvY2tlZF9fO1xuICAgIH0sXG4gICAgbmV3OiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLl9fY291bnRfXyArPSAwO1xuICAgICAgdGhpcy5fX3VubG9ja2VkX18gPSB0cnVlO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgfTtcbiAgaWYgKHdpbmRvdy50YUxvY2sgPT09IHVuZGVmaW5lZCkge1xuICAgIHdpbmRvdy50YUxvY2sgPSB0YUxvY2s7XG4gIH1cblxuICAkLmZuLmV4dGVuZCh7XG4gICAgYW5pbWF0ZUNzczogZnVuY3Rpb24gKGFuaW1hdGlvbk5hbWUpIHtcbiAgICAgIHZhciBhbmltYXRpb25FbmQgPVxuICAgICAgICBcIndlYmtpdEFuaW1hdGlvbkVuZCBtb3pBbmltYXRpb25FbmQgTVNBbmltYXRpb25FbmQgb2FuaW1hdGlvbmVuZCBhbmltYXRpb25lbmRcIjtcbiAgICAgIHRoaXMuYWRkQ2xhc3MoXCJhbmltYXRlZCBcIiArIGFuaW1hdGlvbk5hbWUpLm9uZShhbmltYXRpb25FbmQsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgJCh0aGlzKS5yZW1vdmVDbGFzcyhcImFuaW1hdGVkIFwiICsgYW5pbWF0aW9uTmFtZSk7XG4gICAgICB9KTtcbiAgICB9LFxuICB9KTtcbiAgd2luZG93Ll9HTE9CQUxfREFURV9GTVQgPSBcIllZWVktTU0tREQgSEg6bW06c3NcIjtcblxuICBmdW5jdGlvbiBlcnJSZXNwKHN0YXR1cywgZG9tKSB7XG4gICAgaWYgKHN0YXR1cyA9PSA0MjkpIHtcbiAgICAgICQoZG9tKS5yZW1vdmVDbGFzcyhcImhpZGRlblwiKS50ZXh0KFwi6K+35rGC6L+H5b+r77yM6K+356iN5ZCO5YaN6K+VXCIpO1xuICAgIH0gZWxzZSBpZiAoc3RhdHVzID49IDUwMCkge1xuICAgICAgJChkb20pLnJlbW92ZUNsYXNzKFwiaGlkZGVuXCIpLnRleHQoXCLlhoXpg6jplJnor69cIik7XG4gICAgfSBlbHNlIGlmIChzdGF0dXMgIT0gNDI5ICYmIGVyciA+PSA0MDApIHtcbiAgICAgICQoZG9tKS5yZW1vdmVDbGFzcyhcImhpZGRlblwiKS50ZXh0KFwiNDB4XCIpO1xuICAgIH1cbiAgfVxuXG4gIHdpbmRvdy5lcnJSZXNwID0gZXJyUmVzcDtcblxuICBmdW5jdGlvbiBnZXRTdXBwb3J0RmlsZVN0YXR1cygpIHtcbiAgICBpZiAodHlwZW9mIEZpbGVSZWFkZXIgPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICB3aW5kb3cuZ2V0U3VwcG9ydEZpbGVTdGF0dXMgPSBnZXRTdXBwb3J0RmlsZVN0YXR1cztcblxuICBmdW5jdGlvbiB1bnN1cHBvcnRGaWxlKGVycm9yZG9tKSB7XG4gICAgJChlcnJvcmRvbSlcbiAgICAgIC5yZW1vdmVDbGFzcyhcImhpZGRlblwiKVxuICAgICAgLnRleHQoXCLmgqjnmoTmtY/op4jlmajniYjmnKzkuI3mlK/mjIHmlofku7bkuIrkvKDlip/og73vvIzor7fljYfnuqfmgqjnmoTmtY/op4jlmajvvIFcIik7XG4gIH1cblxuICB3aW5kb3cudW5zdXBwb3J0RmlsZSA9IHVuc3VwcG9ydEZpbGU7XG5cbiAgdmFyIGNvbW1vbl9yZWcgPSB7XG4gICAgaXB2OiBmdW5jdGlvbiAob3B0aW9uKSB7XG4gICAgICByZXR1cm4gL14oXFxzKik/KGh0dHA6XFwvXFwvfGh0dHBzOlxcL1xcLyk/KFxcZCtcXC5cXGQrXFwuXFxkK1xcLlxcZCkoXFw6XFxkezEsNX0pPy8udGVzdChcbiAgICAgICAgb3B0aW9uXG4gICAgICApO1xuICAgIH0sXG4gICAgZG9tYWluOiBmdW5jdGlvbiAob3B0aW9uKSB7XG4gICAgICByZXR1cm4gL14oXFxzKik/KGh0dHA6XFwvXFwvfGh0dHBzOlxcL1xcLyk/W1xcU10rW1xcU10qXFwuW1xcU117Miw0fS9nLnRlc3QoXG4gICAgICAgIG9wdGlvblxuICAgICAgKTtcbiAgICB9LFxuICAgIGRvbWFpbl9vbmx5OiBmdW5jdGlvbiAob3B0aW9uKSB7XG4gICAgICByZXR1cm4gL14oXFxzKik/KGh0dHA6XFwvXFwvfGh0dHBzOlxcL1xcLyk/WzAtOWEtekEtWl9dK1swLTlhLXpBLVpcXC4tXSpcXC5bYS16QS1aXXsyLDR9L2cudGVzdChcbiAgICAgICAgb3B0aW9uXG4gICAgICApO1xuICAgIH0sXG4gICAgcmVzdWx0OiBmdW5jdGlvbiAob3B0aW9uKSB7XG4gICAgICByZXR1cm4gb3B0aW9uXG4gICAgICAgIC50b0xvd2VyQ2FzZSgpXG4gICAgICAgIC5yZXBsYWNlKC9eKFxccyopPyhcXC9cXC8pPyhodHRwOlxcL1xcL3xodHRwczpcXC9cXC8pP3woXFwvXFxTKlxccyopfFxccyokL2csIFwiXCIpO1xuICAgIH0sXG4gIH07XG5cbiAgaWYgKHdpbmRvdy5jb21tb25fcmVnID09PSB1bmRlZmluZWQpIHtcbiAgICB3aW5kb3cuY29tbW9uX3JlZyA9IGNvbW1vbl9yZWc7XG4gIH1cblxuICBpZiAod2luZG93LmlzV3hNaW5pQ29kZVdlYnZpZXdFbnYgPT09IHVuZGVmaW5lZCkge1xuICAgIHdpbmRvdy5pc1d4TWluaUNvZGVXZWJ2aWV3RW52ID1cbiAgICAgIG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL21pbmlwcm9ncmFtL2kpIHx8XG4gICAgICB3aW5kb3cuX193eGpzX2Vudmlyb25tZW50ID09IFwibWluaXByb2dyYW1cIjtcbiAgfVxuXG4gICQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHtcbiAgICAvLyAkKGZ1bmN0aW9uICgpIHtcbiAgICAvLyAgIEZhc3RDbGljay5hdHRhY2goZG9jdW1lbnQuYm9keSk7XG4gICAgLy8gfSk7XG5cbiAgICB0b2FzdHIub3B0aW9ucyA9IHtcbiAgICAgIGNsb3NlQnV0dG9uOiB0cnVlLFxuICAgICAgZGVidWc6IGZhbHNlLFxuICAgICAgbmV3ZXN0T25Ub3A6IGZhbHNlLFxuICAgICAgcHJvZ3Jlc3NCYXI6IGZhbHNlLFxuICAgICAgcG9zaXRpb25DbGFzczogXCJ0b2FzdC1ib3R0b20tY2VudGVyXCIsXG4gICAgICBwcmV2ZW50RHVwbGljYXRlczogZmFsc2UsXG4gICAgICBvbmNsaWNrOiBudWxsLFxuICAgICAgc2hvd0R1cmF0aW9uOiBcIjMwMFwiLFxuICAgICAgaGlkZUR1cmF0aW9uOiBcIjEwMDBcIixcbiAgICAgIHRpbWVPdXQ6IFwiNTAwMFwiLFxuICAgICAgZXh0ZW5kZWRUaW1lT3V0OiBcIjEwMDBcIixcbiAgICAgIHNob3dFYXNpbmc6IFwic3dpbmdcIixcbiAgICAgIGhpZGVFYXNpbmc6IFwibGluZWFyXCIsXG4gICAgICBzaG93TWV0aG9kOiBcImZhZGVJblwiLFxuICAgICAgaGlkZU1ldGhvZDogXCJmYWRlT3V0XCIsXG4gICAgfTtcblxuICAgIC8vXG5cbiAgICAkK
1133FwiI2RvbWFpblwiKS5hdHRyKFxuICAgICAgXCJwbGFjZWhvbGRlclwiLFxuICAgICAgcXVlcnlQYXJhbXNbXCJzZXJ2ZXJfdHlwZVwiXSA9PT0gXCJzc2x2cG5cIlxuICAgICAgICA/IFwiZ20udHJ1c3Rhc2lhLmNvbTo0NDMo56uv5Y+j5Y+v6YCJKVwiXG4gICAgICAgIDogcXVlcnlQYXJhbXNbXCJzZXJ2ZXJfdHlwZVwiXSA9PT0gXCJwcWNfY2hlY2tcIlxuICAgICAgICA/IFwicHFjLnNzbGRlbW8uY246NDQzKOerr+WPo+WPr+mAiSlcIlxuICAgICAgICA6IFwibXlzc2wuY29tOjQ0Myjnq6/lj6Plj6/pgIkpXCJcbiAgICApO1xuXG4gICAgZnVuY3Rpb24gc3VibWl0RGF0YSgpIHtcbiAgICAgIHZhciBzZWFyY2ggPSAkKFwiI2hvbWUtZG9tYWluXCIpLnZhbCgpIHx8ICQoXCIjZG9tYWluXCIpLnZhbCgpIHx8IFwiXCI7XG4gICAgICB2YXIgY2hlY2t0eXBlID0gJChcIiNob21lcGFnZV9jaGVja19uYXYgbGkuYWN0aXZlXCIpLmRhdGEoXCJuYW1lXCIpO1xuICAgICAgdmFyIGlwdiA9IGNvbW1vbl9yZWcuaXB2KHNlYXJjaCk7XG4gICAgICB2YXIgZG9tYWludiA9IGNvbW1vbl9yZWcuZG9tYWluKHNlYXJjaCk7XG4gICAgICBjb25zb2xlLmxvZyhpcHYsIGRvbWFpbnYsIGNoZWNrdHlwZSk7XG4gICAgICBpZiAoZG9tYWludiB8fCBpcHYpIHtcbiAgICAgICAgdmFyIHJlc3VsdGUgPSBjb21tb25fcmVnLnJlc3VsdChzZWFyY2gpO1xuICAgICAgICB2YXIgZG9tYWluID0gXCJcIjtcbiAgICAgICAgdmFyIHBvcnQgPSBcIlwiO1xuICAgICAgICBpZiAocmVzdWx0ZS5pbmRleE9mKFwiOlwiKSA+IC0xKSB7XG4gICAgICAgICAgdmFyIHRlbXAgPSByZXN1bHRlLnNwbGl0KFwiOlwiKTtcbiAgICAgICAgICBkb21haW4gPSB0ZW1wWzBdO1xuICAgICAgICAgIHBvcnQgPSB0ZW1wWzFdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRvbWFpbiA9IHJlc3VsdGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBvcnQgKiAxIDwgNjU1MzYgJiYgcG9ydCAqIDEgPiAwKSB7XG4gICAgICAgICAgJChcIiNyZXBvcnRcIikuYXBwZW5kKFxuICAgICAgICAgICAgJCgnIDxpbnB1dCBuYW1lPVwicG9ydFwiIHR5cGU9XCJoaWRkZW5cIiB2YWx1ZT1cIicgKyBwb3J0ICsgJ1wiPicpXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChcbiAgICAgICAgICBjaGVja3R5cGUgPT0gXCJzc2x2cG5fY2hlY2tcIiB8fFxuICAgICAgICAgIHF1ZXJ5UGFyYW1zW1wic2VydmVyX3R5cGVcIl0gPT09IFwic3NsdnBuXCJcbiAgICAgICAgKSB7XG4gICAgICAgICAgJChcIiNyZXBvcnRcIikuYXBwZW5kKFxuICAgICAgICAgICAgJCgnIDxpbnB1dCBuYW1lPVwic2VydmVyX3R5cGVcIiB0eXBlPVwiaGlkZGVuXCIgdmFsdWU9XCJzc2x2cG5cIj4nKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2hlY2t0eXBlID09IFwiaXB2Nl9jaGVja1wiKSB7XG4gICAgICAgICAgJChcIiNyZXBvcnRcIikuYXBwZW5kKFxuICAgICAgICAgICAgJCgnIDxpbnB1dCBuYW1lPVwiaXB2NlwiIHR5cGU9XCJoaWRkZW5cIiB2YWx1ZT1cIjFcIj4nKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2hlY2t0eXBlID09IFwicHFjX2NoZWNrXCIpIHtcbiAgICAgICAgICB3aW5kb3cub3BlbihcbiAgICAgICAgICAgIFwiL3BxY19jaGVjay5odG1sP2hvc3Q9XCIgKyByZXN1bHRlICsgXCImdmVyaWZ5PTBcIixcbiAgICAgICAgICAgIFwiX2JsYW5rXCJcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgJChcIiNob21lLWRvbWFpblwiKS52YWwoZG9tYWluKTtcbiAgICAgICAgJChcIiNkb21haW5cIikudmFsKGRvbWFpbik7XG4gICAgICAgICQoXCIjcmVwb3J0XCIpLnByb3Aoe1xuICAgICAgICAgIGFjdGlvbjogZG9tYWluLFxuICAgICAgICB9KTtcbiAgICAgICAgJChcIiNyZXBvcnRcIikuc3VibWl0KCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAkKFwiI2NjLXNlYXJjaFwiKS5hZGRDbGFzcyhcImhhcy1lcnJvclwiKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAkK
1133FwiI3NzbC1jaGVja1wiKS5vbihcImNsaWNrXCIsIGZ1bmN0aW9uIChldnQpIHtcbiAgICAgIHN1Ym1pdERhdGEoKTtcbiAgICB9KTtcblxuICAgICQoXCIjbWFpbi1zc2wtY2hlY2tcIikub24oXCJjbGlja1wiLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICBnZXRJbnB1dEhhc2goKTtcbiAgICB9KTtcblxuICAgICQoXCIjbWFpbi1zc2wtbW9uaXRvclwiKS5vbihcImNsaWNrXCIsIGZ1bmN0aW9uIChldnQpIHtcbiAgICAgIHZhciBkb21haW4gPSAkKFwiI2hvbWUtZG9tYWluXCIpLnZhbCgpIHx8IFwiXCI7XG4gICAgICAvLyB2YXIgYmFzZVVybCA9IFwiaHR0cHM6Ly9jbS5teXNzbC5jb20vdXNlci9sb2dpblwiO1xuICAgICAgdmFyIGhvc3RuYW1lID0gXCJcIjtcblxuICAgICAgLy8g5Yik5pat5b2T5YmN5Z+f5ZCN5p2l5Yaz5a6a6Lez6L2s55uu5qCHXG4gICAgICBpZiAod2luZG93LmxvY2F0aW9uLmhvc3RuYW1lLmluZGV4T2YoXCJteXNzbC5jb21cIikgPiAtMSkge1xuICAgICAgICBob3N0bmFtZSA9IFwiaHR0cHM6Ly9jbS5teXNzbC5jb21cIjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhvc3RuYW1lID0gXCJodHRwczovL215Y2VydC5teXNzbC50ZXN0XCI7XG4gICAgICB9XG5cbiAgICAgIHZhciBiYXNlVXJsID0gaG9zdG5hbWUgKyBcIi91c2VyL2xvZ2luXCI7XG5cbiAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgLy8g5riF55CG5Z+f5ZCN77yM56e76Zmk5Y2P6K6u5ZKM56uv5Y+jXG4gICAgICAgIHZhciBjbGVhbkRvbWFpbiA9IGNvbW1vbl9yZWcucmVzdWx0KGRvbWFpbik7XG4gICAgICAgIGlmIChjbGVhbkRvbWFpbi5pbmRleE9mKFwiOlwiKSA+IC0xKSB7XG4gICAgICAgICAgY2xlYW5Eb21haW4gPSBjbGVhbkRvbWFpbi5zcGxpdChcIjpcIilbMF07XG4gICAgICAgIH1cblxuICAgICAgICAvLyDmnoTlu7rph43lrprlkJFVUkxcbiAgICAgICAgdmFyIHJlZGlyZWN0VXJsID1cbiAgICAgICAgICBob3N0bmFtZSArXG4gICAgICAgICAgXCIvbW9uaXRvcj9kPVwiICtcbiAgICAgICAgICBlbmNvZGVVUklDb21wb25lbnQoY2xlYW5Eb21haW4pICtcbiAgICAgICAgICBcIiZzPTEmZnJvbT1teXNzbFwiO1xuICAgICAgICB2Y
1133XIgZmluYWxVcmwgPSBiYXNlVXJsICsgXCI/cmVkaXJlY3Q9XCIgKyBlbmNvZGVVUklDb21wb25lbnQocmVkaXJlY3RVcmwpO1xuXG4gICAgICAgIC8vIOi3s+i9rOWIsOaehOW7uueahFVSTFxuICAgICAgICB3aW5kb3cub3BlbihmaW5hbFVybCwgXCJfYmxhbmtcIik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyDlpoLmnpzmsqHmnInln5/lkI3vvIznm7TmjqXot7PovazliLDnmbvlvZXpobVcbiAgICAgICAgd2luZG93Lm9wZW4oYmFzZVVybCwgXCJfYmxhbmtcIik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAkKFwiI2hvbWUtZG9tYWluLCNkb21haW5cIikub24oXCJmb2N1c1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAkKFwiI2NjLXNlYXJjaFwiKS5yZW1vdmVDbGFzcyhcImhhcy1lcnJvclwiKTtcbiAgICB9KTtcblxuICAgICQoJ1tkYXRhLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG5cbiAgICBpZiAoJChcIiNpc3NzbHZwblwiKS52YWwoKSA9PT0gXCJzc2x2cG5cIikge1xuICAgICAgJChcIi5jYy1sZWZ0LWJyZWFkY3J1bWIgdWwubmF2LXBpbGxzIGxpOmd0KDIpXCIpLmFkZENsYXNzKFwiZGlzYWJsZWRcIik7XG4gICAgICAkKFwiLmNjLWxlZnQtYnJlYWRjcnVtYiB1bC5uYXYtcGlsbHMgbGk6ZXEoNSlcIikucmVtb3ZlQ2xhc3MoXCJkaXNhYmxlZFwiKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBmb3JjZVJlY2hlY2soKSB7XG4gICAgICBxdWVyeVBhcmFtc1tcImZcIl0gPSAxO1xuICAgICAgaWYgKHF1ZXJ5UGFyYW1zLnNlcnZlcl90eXBlID09PSBcInNzbHZwblwiKSB7XG4gICAgICAgIHF1ZXJ5UGFyYW1zW1wic2VydmVyX3R5cGVcIl0gPSBcInNzbHZwblwiO1xuICAgICAgfVxuICAgICAgcXVlcnlQYXJhbXNbXCJzdGF0dXNcIl0gPSBcInFcIjtcbiAgICAgIGRlbGV0ZSBxdWVyeVBhcmFtc1tcImZjXCJdO1xuICAgICAgZGVsZXRlIHF1ZXJ5UGFyYW1zW1wiZmRjXCJdO1xuICAgICAgZGVsZXRlIHF1ZXJ5UGFyYW1zW1wicmVhc29uXCJdO1xuICAgICAgbG9jYXRpb24uc2VhcmNoID0gJC5wYXJhbShxdWVyeVBhcmFtcyk7XG4gICAgfVxuXG4gICAgJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIiNjYy1yZW5ldy1yZXBvcnRcIiwgZm9yY2VSZWNoZWNrKTtcbiAgICAkKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiI2NjLW9uZXJyb3ItcmVjaGVja1wiLCBmb3JjZVJlY2hlY2spO1xuICAgICQoZG9jdW1lbnQpLm9uKFwibW91c2Vtb3ZlXCIsIFwiLmNjLWluZGV4LXRvcGljXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICQoXCIuY2MtaW5kZXgtbGV0cy1jaGVja1wiKS5hbmltYXRlQ3NzKFwicnViYmVyQmFuZFwiKTtcbiAgICB9KTtcblxuICAgIHNldEludGVydmFsKGZ1bmN0aW9uICgpIHtcbiAgICAgICQoXCIuY2MtY2xpY2stZG93biBzcGFuXCIpLmFuaW1hdGVDc3MoXCJwdWxzZVwiKTtcbiAgICB9LCAyMDAwKTtcblxuICAgICQoZG9jdW1lbnQpLm9uKFwiZm9jdXNcIiwgXCJpbnB1dFwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAkKFwiLmNjLWluZGV4LWxldHMtY2hlY2tcIikuYW5pbWF0ZUNzcyhcInJ1YmJlckJhbmRcIik7XG4gICAgfSk7XG5cbiAgICAkK
1133FwiaW5wdXRbbmFtZT0nZG9tYWluJ11cIikuYmluZChcImlucHV0IHByb3BlcnR5Y2hhbmdlXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAkKFwiI2RvbWFpbi1lcnJvclwiKS5hZGRDbGFzcyhcImhpZGRlblwiKTtcbiAgICB9KTtcblxuICAgIC8vIGNvbnNvbGUubG9nKG5hdmlnYXRvci51c2VyQWdlbnQpXG5cbiAgICBmdW5jdGlvbiBteUJyb3dzZXIoKSB7XG4gICAgICB2YXIgdXNlckFnZW50ID0gbmF2aWdhdG9yLnVzZXJBZ2VudDsgLy8g5Y+W5b6X5rWP6KeI5Zmo55qEdXNlckFnZW505a2X56ym5LiyXG4gICAgICB2YXIgaXNPcGVyYSA9IHVzZXJBZ2VudC5pbmRleE9mKFwiT3BlcmFcIikgPiAtMTtcbiAgICAgIGlmIChpc09wZXJhKSB7XG4gICAgICAgIHJldHVybiBcIk9wZXJhXCI7XG4gICAgICB9IC8vIOWIpOaWreaYr+WQpk9wZXJh5rWP6KeI5ZmoXG4gICAgICBpZiAodXNlckFnZW50LmluZGV4T2YoXCJGaXJlZm94XCIpID4gLTEpIHtcbiAgICAgICAgcmV0dXJuIFwiRkZcIjtcbiAgICAgIH0gLy8g5Yik5pat5piv5ZCmRmlyZWZveOa1j+iniOWZqFxuICAgICAgaWYgKHVzZXJBZ2VudC5pbmRleE9mKFwiQ2hyb21lXCIpID4gLTEpIHtcbiAgICAgICAgcmV0dXJuIFwiQ2hyb21lXCI7XG4gICAgICB9XG4gICAgICBpZiAodXNlckFnZW50LmluZGV4T2YoXCJTYWZhcmlcIikgPiAtMSkge1xuICAgICAgICByZXR1cm4gXCJTYWZhcmlcIjtcbiAgICAgIH0gLy8g5Yik5pat5piv5ZCmU2FmYXJp5rWP6KeI5ZmoXG4gICAgICBpZiAoXG4gICAgICAgIHVzZXJBZ2VudC5pbmRleE9mKFwiY29tcGF0aWJsZVwiKSA+IC0xICYmXG4gICAgICAgIHVzZXJBZ2VudC5pbmRleE9mKFwiTVNJRVwiKSA+IC0xICYmXG4gICAgICAgICFpc09wZXJhXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIFwiSUVcIjtcbiAgICAgIH0gLy8g5Yik5pat5piv5ZCmSUXmtY/op4jlmahcbiAgICB9XG5cbiAgICAvLyBpZeezu+WIl+S4jeaUr+aMgXN2Z+WKqOeUu1xuICAgIGZ1bmN0aW9uIEp1ZGdlQnJvc3dlcigpIHtcbiAgICAgIHZhciB0ZW1wID0gXCJcIjtcbiAgICAgIHZhciBzbWFsbHRlbXAgPSBcIlwiO1xuICAgICAgdmFyIHRlbXBsYXRlID0gXy50ZW1wbGF0ZShcbiAgICAgICAgJzxkaXYgY2xhc3M9XCI8JT0gc2NsYXNzICU+IGNjLWxvYWRpbmdcIj5cXFxuICAgICAgICA8ZGl2IGNsYXNzPVwic2stY2lyY2xlMSBzay1jaXJjbGVcIj48L2Rpdj5cXFxuICAgICAgICA8ZGl2IGNsYXNzPVwic2stY2lyY2xlMiBzay1jaXJjbGVcIj48L2Rpdj5cXFxuICAgICAgICA8ZGl2IGNsYXNzPVwic2stY2lyY2xlMyBzay1jaXJjbGVcIj48L2Rpdj5cXFxuICAgICAgICA8ZGl2IGNsYXNzPVwic2stY2lyY2xlNCBzay1jaXJjbGVcIj48L2Rpdj5cXFxuICAgICAgICA8ZGl2IGNsYXNzPVwic2stY2lyY2xlNSBzay1jaXJjbGVcIj48L2Rpdj5cXFxuICAgICAgICA8ZGl2IGNsYXNzPVwic2stY2lyY2xlNiBzay1jaXJjbGVcIj48L2Rpdj5cXFxuICAgICAgICA8ZGl2IGNsYXNzPVwic2stY2lyY2xlNyBzay1jaXJjbGVcIj48L2Rpdj5cXFxuICAgICAgICA8ZGl2IGNsYXNzPVwic2stY2lyY2xlOCBzay1jaXJjbGVcIj48L2Rpdj5cXFxuICAgICAgICA8ZGl2IGNsYXNzPVwic2stY2lyY2xlOSBzay1jaXJjbGVcIj48L2Rpdj5cXFxuICAgICAgICA8ZGl2IGNsYXNzPVwic2stY2lyY2xlMTAgc2stY2lyY2xlXCI+PC9kaXY+XFxcbiAgICAgICAgPGRpdiBjbGFzcz1cInNrLWNpcmNsZTExIHNrLWNpcmNsZVwiPjwvZGl2PlxcXG4gICAgICAgIDxkaXYgY2xhc3M9XCJzay1jaXJjbGUxMiBzay1jaXJjbGVcIj48L2Rpdj5cXFxuICAgICAgPC9kaXY+J1xuICAgICAgKTtcbiAgICAgIHZhciB0ZW1wbGF0ZW90aGVyID0gXy50ZW1wbGF0ZShcbiAgICAgICAgJzxkaXYgY2xhc3M9XCI8JT0gc2NsYXNzICU+XCI+XFxcbiAgICAgIDxzdmcgd2lkdGg9XCIxMDAlXCIgIGhlaWdodD1cIjEwMCVcIiAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMTAwIDEwMFwiIHByZXNlcnZlQXNwZWN0UmF0aW89XCJ4TWlkWU1pZFwiIGNsYXNzPVwibGRzLWdvb2V5LWJhbGxzXCI+XFxcbiAgICAgIDxkZWZzPlxcXG4gICAgICAgIDxmaWx0ZXIgaWQ9XCJnbHVlXCIgeD1cIi0xMDAlXCIgeT1cIi0xMDAlXCIgd2lkdGg9XCIzMDAlXCIgaGVpZ2h0PVwiMzAwJVwiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz1cInNSR0JcIj5cXFxuICAgICAgICAgIDxmZUdhdXNzaWFuQmx1ciBpbj1cIlNvdXJjZUdyYXBoaWNcIiBzdGREZXZpYXRpb249XCIxMFwiPjwvZmVHYXVzc2lhbkJsdXI+XFxcbiAgICAgICAgICA8ZmVDb2xvck1hdHJpeCBtb2RlPVwibWF0cml4XCIgdmFsdWVzPVwiMSAwIDAgMCAwICAgMCAxIDAgMCAwICAgMCAwIDEgMCAwICAgMCAwIDAgNjAgLTQwXCIgcmVzdWx0PVwiY21cIj48L2ZlQ29sb3JNYXRyaXg+XFxcbiAgICAgICAgPC9maWx0ZXI+XFxcbiAgICAgIDwvZGVmcz5cXFxuICAgICAgPGcgZmlsdGVyPVwidXJsKCNnbHVlKVwiPlxcXG4gICAgICAgIDxjaXJjbGUgY3g9XCIyNi45ODk0XCIgY3k9XCI1MFwiIHI9XCIyNC45ODk0XCIgZmlsbD1cIiNmNzMwMDNcIj5cXFxuICAgICAgICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9XCJyXCIgY2FsY01vZGU9XCJzcGxpbmVcIiB2YWx1ZXM9XCIxODsyNTsxOFwiIGtleVRpbWVzPVwiMDswLjU7MVwiIGR1cj1cIjFcIiBrZXlTcGxpbmVzPVwiMC41IDAgMC41IDE7MC41IDAgMC41IDFcIiBiZWdpbj1cIjBz
1133XCIgcmVwZWF0Q291bnQ9XCJpbmRlZmluaXRlXCI+PC9hbmltYXRlPlxcXG4gICAgICAgICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT1cImN4XCIgY2FsY01vZGU9XCJzcGxpbmVcIiB2YWx1ZXM9XCIyMDsyNzsyMFwiIGtleVRpbWVzPVwiMDswLjU7MVwiIGR1cj1cIjFcIiBrZXlTcGxpbmVzPVwiMC41IDAgMC41IDE7MC41IDAgMC41IDFcIiBiZWdpbj1cIjBzXCIgcmVwZWF0Q291bnQ9XCJpbmRlZmluaXRlXCI+PC9hbmltYXRlPlxcXG4gICAgICAgIDwvY2lyY2xlPlxcXG4gICAgICAgIDxjaXJjbGUgY3g9XCI3Mi45ODk0XCIgY3k9XCI1MFwiIHI9XCIxOC4wMTA2XCIgZmlsbD1cIiM1NGU0MDRcIj5cXFxuICAgICAgICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9XCJyXCIgY2FsY01vZGU9XCJzcGxpbmVcIiB2YWx1ZXM9XCIyNTsxODsyNVwiIGtleVRpbWVzPVwiMDswLjU7MVwiIGR1cj1cIjFcIiBrZXlTcGxpbmVzPVwiMC41IDAgMC41IDE7MC41IDAgMC41IDFcIiBiZWdpbj1cIjBzXCIgcmVwZWF0Q291bnQ9XCJpbmRlZmluaXRlXCI+PC9hbmltYXRlPlxcXG4gICAgICAgICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT1cImN4XCIgY2FsY01vZGU9XCJzcGxpbmVcIiB2YWx1ZXM9XCI2Njs3Mzs2NlwiIGtleVRpbWVzPVwiMDswLjU7MVwiIGR1cj1cIjFcIiBrZXlTcGxpbmVzPVwiMC41IDAgMC41IDE7MC41IDAgMC41IDFcIiBiZWdpbj1cIjBzXCIgcmVwZWF0Q291bnQ9XCJpbmRlZmluaXRlXCI+PC9hbmltYXRlPlxcXG4gICAgICAgIDwvY2lyY2xlPlxcXG4gICAgICA8L2c+XFxcbiAgICAgIDwvc3ZnPlxcXG4gICAgICA8L2Rpdj4nXG4gICAgICApO1xuICAgICAgaWYgKCQuYnJvd3Nlci5tc2llIHx8ICQuYnJvd3Nlci5tc2VkZ2UpIHtcbiAgICAgICAgdGVtcCA9IHRlbXBsYXRlKHtcbiAgICAgICAgICBzY2xhc3M6IFwic2stZmFkaW5nLWNpcmNsZVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgc21hbGx0ZW1wID0gdGVtcGxhdGUoe1xuICAgICAgICAgIHNjbGFzczogXCJzay1mYWRpbmctc21hbGwtY2lyY2xlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICAkKFwiLmNjLWNoZWNrLWxvYWRpbmcsLmNjLWNoZWNrLWNlcnQtbG9hZGluZ1wiKS5odG1sKHRlbXApO1xuICAgICAgICAkKFwiLmNjLXNtYWxsLWxvYWRpbmdcIikuaH
1133RtbChzbWFsbHRlbXApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGVtcCA9IHRlbXBsYXRlb3RoZXIoe1xuICAgICAgICAgIHNjbGFzczogXCJjYy1zdmctY2hlY2tpbmdcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHNtYWxsdGVtcCA9IHRlbXBsYXRlb3RoZXIoe1xuICAgICAgICAgIHNjbGFzczogXCJjYy1zbWFsbC1zdmctY2hlY2tpbmdcIixcbiAgICAgICAgfSk7XG4gICAgICAgICQoXCIuY2MtY2hlY2stbG9hZGluZywuY2MtY2hlY2stY2VydC1sb2FkaW5nXCIpLmh0bWwodGVtcCk7XG4gICAgICAgICQoXCIuY2Mtc21hbGwtbG9hZGluZ1wiKS5odG1sKHNtYWxsdGVtcCk7XG4gICAgICB9XG4gICAgICAvLyDku6XkuIvmmK/osIPnlKjkuIrpnaLnmoTlh73mlbBcbiAgICAgIHZhciBtYiA9IG15QnJvd3NlcigpO1xuICAgICAgaWYgKG1iID09IFwiSUVcIikge1xuICAgICAgICB0ZW1wID0gdGVtcGxhdGUoe1xuICAgICAgICAgIHNjbGFzczogXCJzay1mYWRpbmctY2lyY2xlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICBzbWFsbHRlbXAgPSB0ZW1wbGF0ZSh7XG4gICAgICAgICAgc2NsYXNzOiBcInNrLWZhZGluZy1zbWFsbC1jaXJjbGVcIixcbiAgICAgICAgfSk7XG4gICAgICAgICQoXCIuY2MtY2hlY2stbG9hZGluZywuY2MtY2hlY2stY2VydC1sb2FkaW5nXCIpLmh0bWwodGVtcCk7XG4gICAgICAgICQoXCIuY2Mtc21hbGwtbG9hZGluZ1wiKS5odG1sKHNtYWxsdGVtcCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0ZW1wID0gdGVtcGxhdGVvdGhlcih7XG4gICAgICAgICAgc2NsYXNzOiBcImNjLXN2Zy1jaGVja2luZ1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgc21hbGx0ZW1wID0gdGVtcGxhdGVvdGhlcih7XG4gICAgICAgICAgc2NsYXNzOiBcImNjLXNtYWxsLXN2Zy1jaGVja2luZ1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgJChcIi5jYy1jaGVjay1sb2FkaW5nLC5jYy1jaGVjay1jZXJ0LWxvYWRpbmdcIikuaH
1133RtbCh0ZW1wKTtcbiAgICAgICAgJChcIi5jYy1zbWFsbC1sb2FkaW5nXCIpLmh0bWwoc21hbGx0ZW1wKTtcbiAgICAgIH1cbiAgICB9XG4gICAgSnVkZ2VCcm9zd2VyKCk7XG5cbiAgICAkKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiI2NjLW15c3NsLXNlYWxcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgbG9jYXRpb24uaHJlZiA9IFwiL215c3NsLmNvbT9mcm9tPW15c3NsaWRcIjtcbiAgICB9KTtcblxuICAgIGZ1bmN0aW9uIGNoYW5nZVNlYWwoKSB7XG4gICAgICB2YXIgbG9jYWwgPSBsb2NhdGlvbi5vcmlnaW5cbiAgICAgICAgPyBsb2NhdGlvbi5vcmlnaW5cbiAgICAgICAgOiBsb2NhdGlvbi5wcm90b2NvbCArXG4gICAgICAgICAgXCIvL1wiICtcbiAgICAgICAgICBsb2NhdGlvbi5ob3N0bmFtZSArXG4gICAgICAgICAgKGxvY2F0aW9uLnBvcnQgPyBcIjpcIiArIGxvY2F0aW9uLnBvcnQgOiBcIlwiKTtcbiAgICAgIHZhciBzY3JpcHQgPVxuICAgICAgICBcIndpbmRvdy5vcGVuKCdcIiArXG4gICAgICAgIGxvY2FsICtcbiAgICAgICAgXCIvc2VhbC9kZXRhaWw/ZG9tYWluPVwiICtcbiAgICAgICAgbG9jYXRpb24uaG9zdG5hbWUgK1xuICAgICAgICBcIicsJ015U1NM5a6J5YWo562+56ugJywnaGVpZ2h0PTgwMCx3aWR0aD00NzAsdG9wPTAscmlnaHQ9MCx0b29sYmFyPW5vLG1lbnViYXI9bm8sc2Nyb2xsYmFycz1ubyxyZXNpemFibGU9bm8sbG9jYXRpb249bm8sc3RhdHVzPW5vJylcIjtcbiAgICAgIHZhciB0cnVzdFNjcmlwdCA9XG4gICAgICAgIFwid2luZG93Lm9wZW4oJ2h0dHBzOi8vc2VhbC50cnVzdGFzaWEuY29tL3NlYWwvZGV0YWlsP2RvbWFpbj1cIiArXG4gICAgICAgIGxvY2F0aW9uLmhvc3RuYW1lICtcbiAgICAgICAgXCInLCdUcnVzdEFzaWEg5a6J5YWo562+56ugJywnaGVpZ2h0PTgwMCx3aWR0aD00NzAsdG9wPTAscmlnaHQ9MCx0b29sYmFyPW5vLG1lbnViYXI9bm8sc2Nyb2xsYmFycz1ubyxyZXNpemFibGU9bm8sbG9jYXRpb249bm8sc3RhdHVzPW5vJylcIjtcbiAgICAgIHZhciBzaGVsbF9pbmZvID1cbiAgICAgICAgJzxkaXYgdGl0bGU9XCJNeVNTTOWuieWFqOetvueroFwiIGlkPVwibXlzc2xfc2VhbFwiIG9uY2xpY2s9XCInICtcbiAgICAgICAgc2NyaXB0ICtcbiAgICAgICAgJ1wiIHN0eWxlPVwidGV4dC1hbGlnbjogY2VudGVyO2Rpc3BsYXk6IGlubGluZS1ibG9ja1wiPjxpbWcgc3JjPVwiaHR0cHM6Ly9zZWFscmVzLm15c3NsLmNvbS9zZWFsL2ltZy8yeC9zZWFsLnBuZz9kb21haW49JyArXG4gICAgICAgIGxvY2F0aW9uLmhvc3RuYW1lICtcbiAgICAgICAgJ1wiIGFsdD1cIicgK1xuICAgICAgICBsb2NhdGlvbi5ob3N0bmFtZSArXG4gICAgICAgICctTXlTU0zlronlhajnrb7nq6BcIiBzdHlsZT1cIndpZHRoOiAxMDBweDsgaGVpZ2h0OiBhdXRvOyBjdXJzb3I6IHBvaW50ZXJcIj48L2Rpdj4nICtcbiAgICAgICAgJzxkaXYgdGl0bGU9XCJUcnVzdEFzaWEg5a6J5YWo562+56ugXCIgaWQ9XCJteXNzbF9zZWFsXCIgb25jbGljaz1cIicgK1xuICAgICAgICB0cnVzdFNjcmlwdCArXG4gICAgICAgICdcIiBzdHlsZT1cInRleHQtYWxpZ246IGNlbnRlcjtkaXNwbGF5OiBpbmxpbmUtYmxvY2s7aGVpZ2h0OiA2MHB4O1wiPjxpbWcgIHNyYz1cImh0dHBzOi8vc2VhbHJlcy50cnVzdGFzaWEuY29tL3NlYWwvaW1nLzF4L3NlYWwucG5nP2RvbWFpbj0nICtcbiAgICAgICAgbG9jYXRpb24uaG9zdG5hbWUgK1xuICAgICAgICAnXCIgYWx0PVwiVHJ1c3RBc2lhIOWuieWFqOetvueroFwiIHN0eWxlPVwid2lkdGg6IDEzMHB4O2hlaWdodDogYXV0bzsgY3Vyc29yOiBwb2ludGVyOyBwYWRkaW5nLXRvcDogMTBweDsgbWFyZ2luLWxlZnQ6IDE0cHhcIj48L2Rpdj4nICtcbiAgICAgICAgJzxkaXYgY2xhc3M9XCJpdHJ1c3Qtc2VhbFwiIGlkPVwibXlzc2xfc2VhbFwiIHN0eWxlPVwiZGlzcGxheTogaW5saW5lLWJsb2NrXCI+PGEgaWQ9XCJzZWFsX2tub3dzYWZlXCIgaHJlZj1cImh0dHBzOi8vd3d3Lmtub3dzYWZlLmNvbVwiIHNpZD1cImUwNmNiYTFmYTE1NjgxZDg3NDVjNDFkZGIzNGEzN2Q3XCIgc2xhbmc9XCIzXCIgc2RvbWFpbj1cImh0dHBzOi8vc2VhbC5rbm93c2FmZS5jb21cIiB0YXJnZXQ9XCJfYmxhbmtcIj5pVHJ1c3Q8L2E+PC9kaXY+JztcblxuICAgICAgdmFyIG1pbXBpbmdfc2hlbGwgPVxuICAgICAgICAnPGRpdiB0aXRsZT1cIlRydXN0QXNpYSDlronlhajnrb7nq6BcIiBpZD1cIm15c3NsX3NlYWxcIiBvbmNsaWNrPVwiJyArXG4gICAgICAgIHRydXN0U2NyaXB0ICtcbiAgICAgICAgJ1wiIHN0eWxlPVwidGV4dC1hbGlnbjogY2VudGVyO2Rpc3BsYXk6IGlubGluZS1ibG9jaztoZWlnaHQ6IDYwcHg7XCI+PGltZyAgc3JjPVwiaHR0cHM6Ly9zZWFscmVzLnRydXN0YXNpYS5jb20vc2VhbC9pbWcvMXgvc2VhbC5wbmc/ZG9tYWluPScgK1xuICAgICAgICBsb2NhdGlvbi5ob3N0bmFtZSArXG4gICAgICAgICdcIiBhbHQ9XCJUcnVzdEFzaWEg5a6J5YWo562+56ugXCIgc3R5bGU9XCJ3aWR0aDogMTMwcHg7aGVpZ2h0OiBhdXRvOyBjdXJzb3I6IHBvaW50ZXI7IHBhZGRpbmctdG9wOiAxNHB4O1wiPjwvZGl2PicgK1xuICAgICAgICAnPGRpdiBjbGFzcz1cInpoaXh1blwiIGlkPVwiemhpeHVuXCIgc3R5bGU9XCJkaXNwbGF5OiBpbmxpbmUtYmxvY2tcIj48YSBocmVmPVwiaHR0cDovL3d3dy56eGNzZWMuY29tL1wiPjxpbWcgJyArXG4gICAgICAgICdzcmM9XCIvaW1hZ2VzL3poaXh1bi5wbmc/aW1hZ2VWaWV3Mi8wL3cvNzIwL2ludGVybGFjZS8xL3EvNzV8aW1hZ2VzbGltXCIgdGFyZ2V0PVwiX2JsYW5rXCIgc3R5bGU9XCJ3aWR0aDogNTVweDsgaGVpZ2h0OiBhdXRvO3BhZGRpbmctdG9wOiAxMHB4OyBtYXJnaW4tbGVmdDogMjRweFwiJyArXG4gICAgICAgICdhbHQ9XCJ3d3cuenhjc2VjLmNvbVwiIHN0eWxlPVwid2lkdGg6IDM0cHhcIj48L2E+PC9kaXY+JztcblxuICAgICAgJChcIiNjYy1teXNzbC1pZFwiKS5odG1sKHNoZWxsX2luZm8pO1xuICAgICAgJChcIiNjYy1taXBpbmctaWRcIikuaHRtbChtaW1waW5nX3NoZWxsKTtcbiAgICAgIHZhciBpZHZhbHVlID0gXCJcIjtcbiAgICAgIHZhciBsYW5nID0gXCJcIjtcbiAgICAgIHZhciBkb21haW4gPSBcIlwiO
11331xuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIGpzbF9zcGVlZF9zdGF0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzZWFsX2tub3dzYWZlXCIpO1xuICAgICAgICBpZHZhbHVlID1cbiAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInNlYWxfa25vd3NhZmVcIikuYXR0cmlidXRlc1tcInNpZFwiXS52YWx1ZTtcbiAgICAgICAgbGFuZyA9XG4gICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzZWFsX2tub3dzYWZlXCIpLmF0dHJpYnV0ZXNbXCJzbGFuZ1wiXS52YWx1ZTtcbiAgICAgICAgZG9tYWluID1cbiAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInNlYWxfa25vd3NhZmVcIikuYXR0cmlidXRlc1tcInNkb21haW5cIl0udmFsdWU7XG4gICAgICAgIGpzbF9zcGVlZF9zdGF0LnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICB2YXIganNsX3NwZWVkX3N0YXQgPSBudWxsO1xuICAgICAgfVxuICAgICAgJChcIi5pdHJ1c3Qtc2VhbFwiKS5odG1sKFxuICAgICAgICBcIjxhIHRhcmdldD0nX2JsYW5rJyBocmVmPSdcIiArXG4gICAgICAgICAgZG9tYWluICtcbiAgICAgICAgICBcIi9zZWFsL2l0cnVzdGNlcnQ/aWQ9XCIgK1xuICAgICAgICAgIGlkdmFsdWUgK1xuICAgICAgICAgIFwiJmxhbmc9XCIgK1xuICAgICAgICAgIGxhbmcgK1xuICAgICAgICAgIFwiJyB0aXRsZT0naVRydXN0Jz48aW1nIHN0eWxlPSd3aWR0aDogMTE0cHg7IGhlaWdodDogYXV0bztwYWRkaW5nLXRvcDogMTBweDsgbWFyZ2luLWxlZnQ6IDE0cHgnIGJvcmRlcj0nMCcgc3JjPSdcIiArXG4gICAgICAgICAgZG9tYWluICtcbiAgICAgICAgICBcIi9zZWFsL2NlcnRpbWc/aWQ9XCIgK1xuICAgICAgICAgIGlkdmFsdWUgK1xuICAgICAgICAgIFwiJmxhbmc9XCIgK1xuICAgICAgICAgIGxhbmcgK1xuICAgICAgICAgIFwiJz48L2E+XCJcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY2hhbmdlU2VhbCgpO1xuXG4gICAgJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIiNjZG4tY2hlY2tcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgZ29DRE5jaGVjaygpO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gZ29DRE5jaGVjaygpIHtcbiAgICAgIHZhciBzZWFyY2ggPSAkKFwiI2hvbWUtZG9tYWluXCIpLnZhbCgpIHx8IFwiXCI7XG4gICAgICB2Y
1133XIgZG9tYWludiA9IGNvbW1vbl9yZWcuZG9tYWluKHNlYXJjaCk7XG4gICAgICBpZiAoZG9tYWludikge1xuICAgICAgICB2YXIgcmVzdWx0ZSA9IGNvbW1vbl9yZWcucmVzdWx0KHNlYXJjaCk7XG4gICAgICAgIHZhciBkb21haW4gPSBcIlwiO1xuICAgICAgICBpZiAocmVzdWx0ZS5pbmRleE9mKFwiOlwiKSA+IC0xKSB7XG4gICAgICAgICAgdmFyIHRlbXAgPSByZXN1bHRlLnNwbGl0KFwiOlwiKTtcbiAgICAgICAgICBkb21haW4gPSB0ZW1wWzBdO1xuICAgICAgICAgIHBvcnQgPSB0ZW1wWzFdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRvbWFpbiA9IHJlc3VsdGU7XG4gICAgICAgIH1cbiAgICAgICAgJChcIiNob21lLWRvbWFpblwiKS52YWwoZG9tYWluKTtcbiAgICAgICAgbG9jYXRpb24uaHJlZiA9IFwiL2Nkbl9jaGVjay5odG1sP2RvbWFpbj1cIiArIGRvbWFpbjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICQoXCIjY2Mtc2VhcmNoXCIpLmFkZENsYXNzKFwiaGFzLWVycm9yXCIpO1xuICAgICAgfVxuICAgIH1cblxuICAgICQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHtcbiAgICAgICQoXCJzZWxlY3RcIikuc2VsZWN0cmljKHt9KTtcbiAgICAgICQoXCJzZWxlY3QsbGFiZWxcIikuY2hhbmdlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgJChcInNlbGVjdFwiKS5zZWxlY3RyaWMoe30pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAkKGRvY3VtZW50KS5vbihcImtleXByZXNzXCIsIFwiI2RvbWFpblwiLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICB2Y
1133XIga2V5Y29kZSA9IGV2dC5rZXlDb2RlID8gZXZ0LmtleUNvZGUgOiBldnQud2hpY2g7XG4gICAgICBpZiAoa2V5Y29kZSA9PSBcIjEzXCIpIHtcbiAgICAgICAgZXZ0LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHN1Ym1pdERhdGEoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgICQoZG9jdW1lbnQpLm9uKFwia2V5cHJlc3NcIiwgXCIjaG9tZS1kb21haW5cIiwgZnVuY3Rpb24gKGV2dCkge1xuICAgICAgdmFyIGtleWNvZGUgPSBldnQua2V5Q29kZSA/IGV2dC5rZXlDb2RlIDogZXZ0LndoaWNoO1xuICAgICAgaWYgKGtleWNvZGUgPT0gXCIxM1wiKSB7XG4gICAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBnZXRJbnB1dEhhc2goKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmICgkLmJyb3dzZXIubW9iaWxlKSB7XG4gICAgICAkKFwiaW5wdXRbbmFtZT1kb21haW5dLCNjb21tb25fbmFtZSwjY2MtZW1haWwtZG9tYWluXCIpLm9uKGZ1bmN0aW9uIChcbiAgICAgICAgZXZlbnRcbiAgICAgICkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICQoXCJpbnB1dFtuYW1lPWRvbWFpbl0sI2NvbW1vbl9uYW1lLCNjYy1lbWFpbC1kb21haW5cIikuZm9jdXMoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRJbnB1dEhhc2goKSB7XG4gICAgICBpZiAoJChcIiNob21lcGFnZV9jaGVja19uYXYgbGkuY2RuX2NoZWNrXCIpLmhhc0NsYXNzKFwiYWN0aXZlXCIpKSB7XG4gICAgICAgIGdvQ0ROY2hlY2soKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN1Ym1pdERhdGEoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBmaW5kTG9jYXRpb25IYXNoKGxoYXNoKSB7XG4gICAgICAkKFwiI2hvbWVwYWdlX2NoZWNrX25hdiAuXCIgKyBsaGFzaClcbiAgICAgICAgLmFkZENsYXNzKFwiYWN0aXZlXCIpXG4gICAgICAgIC5zaWJsaW5ncyhcImxpXCIpXG4gICAgICAgIC5yZW1vdmVDbGFzcyhcImFjdGl2ZVwiKTtcbiAgICAgIGlmIChsaGFzaCA9PSBcInNzbHZwbl9jaGVja1wiKSB7XG4gICAgICAgICQoXCIuY2MtZ20tcGxhY2Vob2xkZXJcIikuY3NzKFwiZGlzcGxheVwiLCBcImJsb2NrXCIpO1xuICAgICAgICAkKFwiLmNjLW5vcm1hbC1wbGFjZWhvbGRlclwiKS5jc3MoXCJkaXNwbGF5XCIsIFwibm9uZVwiKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICQoXCIuY2MtZ20tcGxhY2Vob2xkZXJcIikuY3NzKFwiZGlzcGxheVwiLCBcIm5vbmVcIik7XG4gICAgICAgICQoXCIuY2Mtbm9ybWFsLXBsYWNlaG9sZGVyXCIpLmNzcyhcImRpc3BsYXlcIiwgXCJibG9ja1wiKTtcbiAgICAgIH1cbiAgICAgIGlmIChsaGFzaCA9PT0gXCJlbWFpbF9jaGVja1wiKSB7XG4gICAgICAgICQoXCIjaG9tZS1kb21haW5cIikuYXR0cihcInBsYWNlaG9sZGVyXCIsIFwic210cC5xcS5jb206NDY1XCIpO1xuICAgICAgICAkKFwiI2hvbWUtZG9tYWluXCIpLnZhbChcInNtdHAucXEuY29tOjQ2NVwiKTtcbiAgICAgIH0gZWxzZSBpZiAobGhhc2ggPT0gXCJzc2x2cG5fY2hlY2tcIikge1xuICAgICAgICAkKFwiI2hvbWUtZG9tYWluXCIpLmF0dHIoXCJwbGFjZWhvbGRlclwiLCBcImdtLnRydXN0YXNpYS5jb21cIik7XG4gICAgICAgICQoXCIjaG9tZS1kb21haW5cIikudmFsKFwiZ20udHJ1c3Rhc2lhLmNvbVwiKTtcbiAgICAgIH0gZWxzZSBpZiAobGhhc2ggPT0gXCJwcWNfY2hlY2tcIikge1xuICAgICAgICAkKFwiI2hvbWUtZG9tYWluXCIpLmF0dHIoXCJwbGFjZWhvbGRlclwiLCBcInBxYy5zc2xkZW1vLmNuXCIpO1xuICAgICAgICAkKFwiI2hvbWUtZG9tYWluXCIpLnZhbChcInBxYy5zc2xkZW1vLmNuXCIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgJChcIiNob21lLWRvbWFpblwiKS5hdHRyKFwicGxhY2Vob2xkZXJcIiwgXCJteXNzbC5jb21cIik7XG4gICAgICAgICQoXCIjaG9tZS1kb21haW5cIikudmFsKFwiXCIpO1xuICAgICAgfVxuXG4gICAgICAvLyAkKHRoaXMpLmF0dHIoJ3BsYWNlaG9sZG
1133VyJyxcIlwiKTtcbiAgICAgIC8vICQoJy50YWItY29udGVudCAuJyArIGxoYXNoKS5hZGRDbGFzcygnYWN0aXZlJykuc2libGluZ3MoJ2RpdicpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICB9XG5cbiAgICAkKFwiI2hvbWVwYWdlX2NoZWNrX25hdiBsaSBhXCIpLm9uKFwiY2xpY2tcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIGxoYXNoID0gJCh0aGlzKS5hdHRyKFwiYWx0XCIpO1xuICAgICAgZmluZExvY2F0aW9uSGFzaChsaGFzaCk7XG4gICAgfSk7XG5cbiAgICBpZiAobG9jYXRpb24uaGFzaCAmJiBsb2NhdGlvbi5oYXNoID09IFwiI2dtc3NsXCIpIHtcbiAgICAgICQoXCIjaG9tZXBhZ2VfY2hlY2tfbmF2IC5zc2x2cG5fY2hlY2tcIilcbiAgICAgICAgLmFkZENsYXNzKFwiYWN0aXZlXCIpXG4gICAgICAgIC5zaWJsaW5ncyhcImxpXCIpXG4gICAgICAgIC5yZW1vdmVDbGFzcyhcImFjdGl2ZVwiKTtcbiAgICAgICQoXCIuY2MtZ20tcGxhY2Vob2xkZXJcIikuY3NzKFwiZGlzcGxheVwiLCBcImJsb2NrXCIpO1xuICAgICAgJChcIi5jYy1ub3JtYWwtcGxhY2Vob2xkZXJcIikuY3NzKFwiZGlzcGxheVwiLCBcIm5vbmVcIik7XG4gICAgICAkKFwiI2hvbWUtZG9tYWluXCIpLmF0dHIoXCJwbGFjZWhvbGRlclwiLCBcImdtLnRydXN0YXNpYS5jb21cIik7XG4gICAgICAkKFwiI2hvbWUtZG9tYWluXCIpLnZhbChcImdtLnRydXN0YXNpYS5jb21cIik7XG4gICAgfVxuXG4gICAgLy8gJCgnI2NjLW5hdmJhci1jb2xsYXBzZScpIOaVtOS4quWkp25hdlxuICAgIC8vIGhlYWRpbmdPbmUgIGNvbGxhcHNlT25lICDlt6XlhbfnrrFcbiAgICAvLyBzZWNvbmQtbGV2ZWwtYnRuIGNvbGxhcHNlQ29udGFpbiDlt6XlhbfnrrHkuIvnmoTnrKzkuozlsYJcblxuICAgIGZ1bmN0aW9uIGZpeENvbGxwc2UoKSB7XG4gICAgICBpZiAoJCh3aW5kb3cpLndpZHRoKCkgPiA3NjgpIHtcbiAgICAgICAgJChcIiNjYy1uYXZiYXItY29sbGFwc2UsLmNvbGxhcHNlQ29udGFpblwiKS5zaG93KCk7XG4gICAgICB9IGVsc2UgaWYgKCQod2luZG93KS53aWR0aCgpIDwgNzY4KSB7XG4gICAgICAgICQoXCIjY2MtbmF2YmFyLWNvbGxhcHNlLC5jb2xsYXBzZUNvbnRhaW4sI2NvbGxhcHNlT25lXCIpLmhpZGUoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmaXhDb2xscHNlKCk7XG5cbiAgICAkKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLmNjLW5hdmJhci1idG5cIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICQoXCIjY2MtbmF2YmFyLWNvbGxhcHNlXCIpLnRvZ2dsZSgpO1xuICAgIH0pO1xuXG4gICAgJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIiNjYy1uYXZiYXItY29sbGFwc2VcIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgICAkKHdpbmRvdykucmVzaXplKGZ1bmN0aW9uICgpIHtcbiAgICAgIGZpeENvbGxwc2UoKTtcbiAgICB9KTtcblxuICAgICQoZG9jdW1lbnQpLm9uKFwiY2xpY2tcIiwgXCIjaGVhZGluZ09uZVwiLCBmdW5jdGlvbiAoZSkge1xuICAgICAgJChcIiNjb2xsYXBzZU9uZVwiKS50b2dnbGUoKTtcblxuICAgICAgJChkb2N1bWVudCkub25lKFwiY2xpY2tcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAkKFwiI2NvbGxhcHNlT25lXCIpLmhpZGUoKTtcbiAgICAgIH0pO1xuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9KTtcblxuICAgICQoZG9jdW1lbnQpLm9uKFwiY2xpY2tcIiwgXCIjY29sbGFwc2VPbmVcIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgICAkKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLnNlY29uZC1sZXZlbC1idG5cIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAkKHRoaXMpLnBhcmVudChcImRpdlwiKS5zaWJsaW5ncyhcIi5jb2xsYXBzZUNvbnRhaW5cIikudG9nZ2xlKCk7XG4gICAgfSk7XG5cbiAgICAkK
1133FwiI2RvbWFpbi1lcnJvci1jbG9zZVwiKS5vbihcImNsaWNrXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICQoXCIjZG9tYWluLWVycm9yXCIpLmFkZENsYXNzKFwiaGlkZGVuXCIpO1xuICAgIH0pO1xuXG4gICAgJChcbiAgICAgIFwiI2NjLXVwbG9hZC10ZXh0LCNjYy11cGxvYWQtdGV4dC1vdGhlciwjY2MtdG9kZWNyeXB0LXRleHQsICNjYy1kZWNyeXB0LXRleHQsICNjYy10b3RjLXRleHQsI2NjLWV2ZWxvcGUtdGV4dCwjY2Mta2V5LXRleHQsI2NjLWtleS10ZW1wLXRleHQsICNjYy10Yy10ZXh0LCAjY2MtZ210b2RlY3J5cHQtdGV4dCwgI2NjLWdtZGVjcnlwdC10ZXh0XCJcbiAgICApLm9uKHtcbiAgICAgIGZvY3VzOiBmdW5jdGlvbiAocGFyYW0pIHtcbiAgICAgICAgJCh0aGlzKS5uZXh0KFwiZGl2XCIpLmhpZGUoKTtcbiAgICAgICAgJChcIi5jYy11cGxvYWQtYm94IGlucHV0XCIpLnZhbCgpID09IFwiXCI7XG4gICAgICB9LFxuICAgICAgYmx1cjogZnVuY3Rpb24gKHBhcmFtKSB7XG4gICAgICAgICQoXCIuY2MtdXBsb2FkLWJveCBpbnB1dFwiKS52YWwoKSA9PSBcIlwiO1xuICAgICAgICBpZiAoJCh0aGlzKS52YWwoKSA9PSBcIlwiKSB7XG4gICAgICAgICAgJCh0aGlzKS5uZXh0KFwiZGl2XCIpLnNob3coKTtcbiAgICAgICAgfSBlbHNlIGlmICgkKHRoaXMpLnZhbCgpICE9PSBcIlwiKSB7XG4gICAgICAgICAgJCh0aGlzKS5uZXh0KFwiZGl2XCIpLmhpZGUoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcblxuICAgICQoZG9jdW1lbnQpLm9uKFwiY2xpY2tcIiwgXCIuY29weS1idG5cIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICB2Y
1133XIgdGV4dCA9ICQodGhpcykuYXR0cihcImRhdGEtY2xpcGJvYXJkLXRleHRcIik7XG4gICAgICB2YXIgJGJ0biA9ICQodGhpcyk7XG5cbiAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmRcbiAgICAgICAgLndyaXRlVGV4dCh0ZXh0KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdmFyIG9yaWdpbmFsVGV4dCA9ICRidG4udGV4dCgpO1xuICAgICAgICAgICRidG4udGV4dChcIuW3suWkjeWItiFcIik7XG4gICAgICAgICAgJGJ0bi5hZGRDbGFzcyhcImNvcGllZFwiKTtcblxuICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgJGJ0bi50ZXh0KG9yaWdpbmFsVGV4dCk7XG4gICAgICAgICAgICAkYnRuLnJlbW92ZUNsYXNzKFwiY29waWVkXCIpO1xuICAgICAgICAgIH0sIDIwMDApO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCLlpI3liLblpLHotKU6XCIsIGVycik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gS2V5TWFuYWdlciDmmbrog73kuIvovb3lip/og71cbiAgICAkKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiI2tleW1hbmFnZXItbWFpbi1kb3dubG9hZC1idG5cIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHdpbmRvdy5LZXlNYW5hZ2VyRG93bmxvYWQuZG93bmxvYWRLZXlNYW5hZ2VyKG51bGwsIHRoaXMpO1xuICAgIH0pO1xuXG4gICAgLy8gTWFjIOeUqOaIt++8muWIneWni+WMluiKr+eJh+mAieaLqeS4i+i9vemTvuaOpVxuICAgIHdpbmRvdy5LZXlNYW5hZ2VyRG93bmxvYWQuaW5pdE1hY0Rvd25sb2FkTGlua3MoKTtcblxuICAgIC8vIOmhtemdouWwsee7quWNs+mihOaLieWPluacgOaWsOeJiOacrOWPt++8jOeCueWHu+S4i+i9veaXtuaXoOmcgOetieW+hVxuICAgIHdpbmRvdy5LZXlNYW5hZ2VyRG93bmxvYWQucHJlbG9hZFZlcnNpb24oKTtcblxuICAgICQoZG9jdW1lbnQpLm9uKFwiY2xpY2tcIiwgXCIua20tbWFjLWRvd25sb2FkXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB2Y
1133XIgY2hpcCA9ICQodGhpcykuZGF0YShcImNoaXBcIik7XG4gICAgICB3aW5kb3cuS2V5TWFuYWdlckRvd25sb2FkLmRvd25sb2FkS2V5TWFuYWdlcihjaGlwLCB0aGlzKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gS2V5TWFuYWdlciDlhazlhbHkuIvovb3lip/og71cbiAgd2luZG93LktleU1hbmFnZXJEb3dubG9hZCA9IHtcbiAgICAvLyDlubPlj7Dmo4DmtYvlh73mlbBcbiAgICBkZXRlY3RQbGF0Zm9ybTogZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgdXNlckFnZW50ID0gbmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpO1xuICAgICAgdmFyIHBsYXRmb3JtID0gbmF2aWdhdG9yLnBsYXRmb3JtLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG1hY29zOiAvbWFjLy50ZXN0KHBsYXRmb3JtKSB8fCAvbWFjaW50b3NoLy50ZXN0KHVzZXJBZ2VudCksXG4gICAgICAgIHdpbmRvd3M6IC93aW4vLnRlc3QocGxhdGZvcm0pIHx8IC93aW5kb3dzLy50ZXN0KHVzZXJBZ2VudCksXG4gICAgICAgIGxpbnV4OiAvbGludXgvLnRlc3QocGxhdGZvcm0pIHx8IC94MTEvLnRlc3QocGxhdGZvcm0pLFxuICAgICAgfTtcbiAgICB9LFxuXG4gICAgLy8g566A5Y2V55qEWUFNTOino+aekOWHveaVsFxuICAgIHBhcnNlWUFNTDogZnVuY3Rpb24oeWFtbFRleHQpIHtcbiAgICAgIHZhciBsaW5lcyA9IHlhbWxUZXh0LnNwbGl0KFwiXFxuXCIpO1xuICAgICAgdmFyIHJlc3VsdCA9IHt9O1xuXG4gICAgICBsaW5lcy5mb3JFYWNoKGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgIHZhciB0cmltbWVkTGluZSA9IGxpbmUudHJpbSgpO1xuICAgICAgICBpZiAodHJpbW1lZExpbmUgJiYgIXRyaW1tZWRMaW5lLnN0YXJ0c1dpdGgoXCIjXCIpKSB7XG4gICAgICAgICAgdmFyIGNvbG9uSW5kZXggPSB0cmltbWVkTGluZS5pbmRleE9mKFwiOlwiKTtcbiAgICAgICAgICBpZiAoY29sb25JbmRleCA+IDApIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSB0cmltbWVkTGluZS5zdWJzdHJpbmcoMCwgY29sb25JbmRleCkudHJpbSgpO1xuICAgICAgICAgICAgdmFyIHZhbHVlID0gdHJpbW1lZExpbmUuc3Vic3RyaW5nKGNvbG9uSW5kZXggKyAxKS50cmltKCk7XG4gICAgICAgICAgICByZXN1bHRba2V5XSA9IHZhbHVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSxcblxuICAgIC8vIE1hYyDnlKjmiLfvvJrliJ3lp4vljJboiq/niYfpgInmi6nkuIvovb3pk77mjqXvvIzmm7/mjaLpobXpnaLkuIrmiYDmnIkgS2V5TWFuYWdlciDkuIvovb3lhaXlj6NcbiAgICBpbml0TWFjRG93bmxvYWRMaW5rczogZnVuY3Rpb24oKSB7XG4gICAgICB2Y
1133XIgcGxhdGZvcm0gPSB0aGlzLmRldGVjdFBsYXRmb3JtKCk7XG4gICAgICBpZiAoIXBsYXRmb3JtLm1hY29zKSByZXR1cm47XG5cbiAgICAgICQoXCIja2V5bWFuYWdlci1tYWluLWRvd25sb2FkLWJ0blwiKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgJGxpbmsgPSAkKHRoaXMpO1xuICAgICAgICB2YXIgJHJlcGxhY2VtZW50ID0gJCgnPHNwYW4gY2xhc3M9XCJrbS1tYWMtY2hpcC1saW5rc1wiPjwvc3Bhbj4nKTtcbiAgICAgICAgJHJlcGxhY2VtZW50LmFwcGVuZChcbiAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJnbHlwaGljb24gZ2x5cGhpY29uLWRvd25sb2FkLWFsdFwiPjwvc3Bhbj4g5LiL6L29IEtleU1hbmFnZXLvvJonXG4gICAgICAgICk7XG4gICAgICAgICRyZXBsYWNlbWVudC5hcHBlbmQoXG4gICAgICAgICAgJzxhIGhyZWY9XCIjXCIgY2xhc3M9XCJrbS1tYWMtZG93bmxvYWQga2V5bWFuYWdlci1kb3dubG9hZC1saW5rXCIgZGF0YS1jaGlwPVwiaW50ZWxcIj5JbnRlbCDoiq/niYfniYg8L2E+J1xuICAgICAgICApO1xuICAgICAgICAkcmVwbGFjZW1lbnQuYXBwZW5kKFwiIC8gXCIpO1xuICAgICAgICAkcmVwbGFjZW1lbnQuYXBwZW5kKFxuICAgICAgICAgICc8YSBocmVmPVwiI1wiIGNsYXNzPVwia20tbWFjLWRvd25sb2FkIGtleW1hbmFnZXItZG93bmxvYWQtbGlua1wiIGRhdGEtY2hpcD1cImFwcGxlXCI+QXBwbGUg6Iqv54mH54mIPC9hPidcbiAgICAgICAgKTtcbiAgICAgICAgJGxpbmsucmVwbGFjZVdpdGgoJHJlcGxhY2VtZW50KTtcbiAgICAgIH0pO1xuXG4gICAgICAkKFwiI2tleW1hbmFnZXItZG93bmxvYWQtYnRuXCIpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciAkbGluayA9ICQodGhpcyk7XG4gICAgICAgIHZhciAkcmVwbGFjZW1lbnQgPSAkKCc8c3BhbiBjbGFzcz1cImttLW1hYy1jaGlwLWxpbmtzXCI+PC9zcGFuPicpO1xuICAgICAgICAkcmVwbGFjZW1lbnQuYXBwZW5kKFxuICAgICAgICAgICc8YSBocmVmPVwiI1wiIGNsYXNzPVwia20tbWFjLWRvd25sb2FkIGtleW1hbmFnZXItZG93bmxvYWQtbGlua1wiIGRhdGEtY2hpcD1cImludGVsXCI+SW50ZWwg6Iqv54mH54mIPC9hPidcbiAgICAgICAgKTtcbiAgICAgICAgJHJlcGxhY2VtZW50LmFwcGVuZChcIiAvIFwiKTtcbiAgICAgICAgJHJlcGxhY2VtZW50LmFwcGVuZChcbiAgICAgICAgICAnPGEgaHJlZj1cIiNcIiBjbGFzcz1cImttLW1hYy1kb3dubG9hZCBrZXltYW5hZ2VyLWRvd25sb2FkLWxpbmtcIiBkYXRhLWNoaXA9XCJhcHBsZVwiPkFwcGxlIOiKr+eJh+eJiDwvYT4nXG4gICAgICAgICk7XG4gICAgICAgICRsaW5rLnJlcGxhY2VXaXRoKCRyZXBsYWNlbWVudCk7XG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgLy8g6aKE5Yqg6L2954q25oCB77ya57yT5a2Y6L+b6KGM5Lit5oiW5bey5a6M5oiQ55qE54mI5pys5Y+36K+35rGC77yM6YG/5YWN54K55Ye75pe25YaN5Y+R5LiA5qyhXG4gICAgX3ZlcnNpb25Qcm9taXNlOiBudWxsLFxuXG4gICAgLy8g6aKE5ouJ5Y+W5pyA5paw54mI5pys5Y+377yb5aSx6LSl5pe25riF5o6J57yT5a2Y5Lul5L6/5LiL5qyh6YeN6K+VXG4gICAgcHJlbG9hZFZlcnNpb246IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgIGlmIChzZWxmLl92ZXJzaW9uUHJvbWlzZSkgcmV0dXJuIHNlbGYuX3ZlcnNpb25Qcm9taXNlO1xuXG4gICAgICBzZWxmLl92ZXJzaW9uUHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICB2Y
1133XIgYXBpVXJsID1cbiAgICAgICAgICBcImh0dHBzOi8va2V5bWFuYWdlci50cnVzdGFzaWEuY29tL3JlbGVhc2UvbGF0ZXN0LnltbD9yZWZyZXNoPVwiICtcbiAgICAgICAgICBEYXRlLnBhcnNlKG5ldyBEYXRlKCkpO1xuXG4gICAgICAgIHhoci5vcGVuKFwiR0VUXCIsIGFwaVVybCwgdHJ1ZSk7XG4gICAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaWYgKHhoci5yZWFkeVN0YXRlICE9PSBYTUxIdHRwUmVxdWVzdC5ET05FKSByZXR1cm47XG4gICAgICAgICAgaWYgKHhoci5zdGF0dXMgIT09IDIwMCkge1xuICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIkhUVFAgXCIgKyB4aHIuc3RhdHVzKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YXIgeWFtbERhdGEgPSBzZWxmLnBhcnNlWUFNTCh4aHIucmVzcG9uc2VUZXh0KTtcbiAgICAgICAgICAgIGlmICh5YW1sRGF0YS52ZXJzaW9uKSB7XG4gICAgICAgICAgICAgIHJlc29sdmUoeWFtbERhdGEudmVyc2lvbik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKFwi5peg5rOV6Kej5p6Q54mI5pys5L+h5oGvXCIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgeGhyLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIue9kee7nOivt+axguWksei0pVwiKSk7XG4gICAgICAgIH07XG4gICAgICAgIHhoci5zZW5kKCk7XG4gICAgICB9KTtcblxuICAgICAgc2VsZi5fdmVyc2lvblByb21pc2UuY2F0Y2goZnVuY3Rpb24gKGVycikge1xuICAgICAgICBjb25zb2xlLmVycm9yKFwi6aKE5Yqg6L29IEtleU1hbmFnZXIg54mI5pys5aSx6LSlOlwiLCBlcnIpO1xuICAgICAgICBzZWxmLl92ZXJzaW9uUHJvbWlzZSA9IG51bGw7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHNlbGYuX3ZlcnNpb25Qcm9taXNlO1xuICAgIH0sXG5cbiAgICAvLyDmoLnmja7niYjmnKzlj7fkuI7oiq/niYfnsbvlnovmnoTlu7rlr7nlupTlubPlj7DnmoTkuIvovb3pk77mjqVcbiAgICBidWlsZERvd25sb2FkVXJsOiBmdW5jdGlvbiAodmVyc2lvbiwgY2hpcCkge1xuICAgICAgdmFyIHBsYXRmb3JtID0gdGhpcy5kZXRlY3RQbGF0Zm9ybSgpO1xuICAgICAgdmFyIGJhc2VVcmwgPSBcImh0dHBzOi8va2V5bWFuYWdlci50cnVzdGFzaWEuY29tL3JlbGVhc2UvXCI7XG5cbiAgICAgIGlmIChwbGF0Zm9ybS5tYWNvcykge1xuICAgICAgICByZXR1cm4gY2hpcCA9PT0gXCJhcHBsZVwiXG4gICAgICAgICAgPyBiYXNlVXJsICsgXCJLZXlNYW5hZ2VyLVwiICsgdmVyc2lvbiArIFwiLWFybTY0LmRtZ1wiXG4gICAgICAgICAgOiBiYXNlVXJsICsgXCJLZXlNYW5hZ2VyLVwiICsgdmVyc2lvbiArIFwiLmRtZ1wiO1xuICAgICAgfVxuICAgICAgaWYgKHBsYXRmb3JtLmxpbnV4KSB7XG4gICAgICAgIHJldHVybiBiYXNlVXJsICsgXCJLZXlNYW5hZ2VyLVwiICsgdmVyc2lvbiArIFwiLkFwcEltYWdlXCI7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZVVybCArIFwiS2V5TWFuYWdlci1TZXR1cC1cIiArIHZlcnNpb24gKyBcIi5leGVcIjtcbiAgICB9LFxuXG4gICAgLy8gS2V5TWFuYWdlcuS4i+i9veWHveaVsO+8jGNoaXAg5Y+C5pWw5LuFIE1hYyDkvb/nlKjvvJonaW50ZWwnIOaIliAnYXBwbGUnXG4gICAgZG93bmxvYWRLZXlNYW5hZ2VyOiBmdW5jdGlvbiAoY2hpcCwgdHJpZ2dlckVsZW1lbnQpIHtcbiAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgIHZhciAkYnRuID0gdHJpZ2dlckVsZW1lbnRcbiAgICAgICAgPyAkKHRyaWdnZXJFbGVtZW50KVxuICAgICAgICA6ICQoXCIja2V5bWFuYWdlci1tYWluLWRvd25sb2FkLWJ0blwiKTtcbiAgICAgIHZhciBvcmlnaW5hbFRleHQgPSAkYnRuLnRleHQoKTtcblxuICAgICAgdmFyIHZlcnNpb25Qcm9taXNlID0gc2VsZi5wcmVsb2FkVmVyc2lvbigpO1xuXG4gICAgICAvLyDoi6XpooTliqDovb3lsJrmnKrlrozmiJDliJnlsZXnpLrliqDovb3mgIHvvIzlkb3kuK3nvJPlrZjml7bot7Pov4fku6Xpgb/lhY3mloflrZfpl6rng4FcbiAgICAgIHZhciBzZXR0bGVkID0gZmFsc2U7XG4gICAgICB2Y
1133XIgbG9hZGluZ1RpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghc2V0dGxlZCkge1xuICAgICAgICAgICRidG4udGV4dChcIuato+WcqOiOt+WPluacgOaWsOeJiOacrC4uLlwiKS5jc3MoXCJwb2ludGVyLWV2ZW50c1wiLCBcIm5vbmVcIik7XG4gICAgICAgIH1cbiAgICAgIH0sIDApO1xuXG4gICAgICB2ZXJzaW9uUHJvbWlzZVxuICAgICAgICAudGhlbihmdW5jdGlvbiAodmVyc2lvbikge1xuICAgICAgICAgIHNldHRsZWQgPSB0cnVlO1xuICAgICAgICAgIGNsZWFyVGltZW91dChsb2FkaW5nVGltZXIpO1xuICAgICAgICAgIHZhciBkb3dubG9hZFVybCA9IHNlbGYuYnVpbGREb3dubG9hZFVybCh2ZXJzaW9uLCBjaGlwKTtcbiAgICAgICAgICAkYnRuLnRleHQoXCLmraPlnKjkuIvovb0uLi5cIikuY3NzKFwicG9pbnRlci1ldmVudHNcIiwgXCJub25lXCIpO1xuICAgICAgICAgIHdpbmRvdy5vcGVuKGRvd25sb2FkVXJsLCBcIl9ibGFua1wiKTtcbiAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICRidG4udGV4dChvcmlnaW5hbFRleHQpLmNzcyhcInBvaW50ZXItZXZlbnRzXCIsIFwiXCIpO1xuICAgICAgICAgIH0sIDIwMDApO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgIHNldHRsZWQgPSB0cnVlO1xuICAgICAgICAgIGNsZWFyVGltZW91dChsb2FkaW5nVGltZXIpO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJLZXlNYW5hZ2VyIOS4i+i9veWksei0pTpcIiwgZXJyKTtcbiAgICAgICAgICAkYnRuLnRleHQoXCLkuIvovb3lpLHotKXvvIzor7fph43or5VcIikuY3NzKFwicG9pbnRlci1ldmVudHNcIiwgXCJcIik7XG4gICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAkYnRuLnRleHQob3JpZ2luYWxUZXh0KS5jc3MoXCJwb2ludGVyLWV2ZW50c1wiLCBcIlwiKTtcbiAgICAgICAgICB9LCAzMDAwKTtcbiAgICAgICAgfSk7XG4gICAgfSxcbiAgfTtcbn0pKHdpbmRvdyk7XG4iXSwiZmlsZSI6Im1haW4uanMifQ==

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.